home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / spreadsheets / a180_1 / !SSS / c / graph < prev    next >
Text File  |  1991-07-30  |  5KB  |  185 lines

  1. /* graphic functions for SSS */
  2. /* Tue,30 Jul 1991 */
  3. /* Copyright C.T.Stretch 1991 */
  4.  
  5. #include "ssshdr.h"
  6. #include "drhdr.h"
  7.  
  8. static void *dfile=0;
  9. static char num[128];
  10.  
  11. static double marksize(double r)
  12. { double d=pow(10,floor(log10(r)));
  13.   if(r/d>=5) return 5*d;
  14.   if(r/d>=2) return 2*d;
  15.   return d;
  16. }
  17.  
  18.  
  19. static BOOL cellpr(int x,int y)
  20. { entry *ce=sheet[x+y*NCOLS];
  21.   if(!ce) return FALSE;
  22.   if(ce->p) return FALSE;
  23.   if(ce->a) return FALSE;
  24.   switch(ce->t)
  25.       { case FSTRING:
  26.         case FLONG:sprintf(num,"%.*s",127,&(ce->c));break;
  27.         case FINT:sprintf(num,"%.0f",ce->v);break;
  28.         case F2DP:sprintf(num,"%.2f",ce->v);break;
  29.         case F4DP:sprintf(num,"%.4f",ce->v);break;
  30.         case FEXP:sprintf(num,"%.4e",ce->v);break;
  31.       }
  32.   return TRUE;
  33. }
  34.  
  35.  
  36. static void ylab(double x,double y)
  37. { char s[32];
  38.   sprintf(s,"%g",y);
  39.   dr_printl(x,y,s);
  40. }
  41.  
  42.  
  43. static void xlab(double x,double y)
  44. { char s[32];
  45.   sprintf(s,"%g",x);
  46.   dr_printu(x,y,s);
  47. }
  48.  
  49. BOOL graph_bars(char *fn,void *v)
  50. { double ymin=0,ymax=0;
  51.   double eps=0,xedge,yedge,mark,ym;
  52.   int x,y,col=0;
  53.   entry *cb;
  54.   v=v;
  55.   for(x=ex0;x<=ex1;x++) for(y=ey0;y<=ey1;y++)
  56.   { cb=sheet[x+NCOLS*y];
  57.     if(cb&&cb->t>=FINT&&!(cb->p||cb->a))
  58.     { if(cb->v<ymin) ymin=cb->v;
  59.       if(cb->v>ymax) ymax=cb->v;
  60.     }
  61.   }
  62.   xedge=(ey1+1-ey0)*.125;
  63.   if(ymax<=ymin) ymax+=1;
  64.   yedge=(ymax-ymin)*.125;
  65.   dr_start(&dfile);
  66.   dr_scale(ey0-xedge,ymin-yedge,ey1+1+xedge,ymax+yedge);
  67.   dr_psize(xedge/(width[ex0]+1));
  68.   mark=marksize((ymax-ymin)/6);
  69.   dr_path();
  70.   for(ym=0;ym<=ymax;ym+=mark) { dr_move(ey0,ym);dr_draw(ey1+1,ym);}
  71.   for(ym=-mark;ym>=ymin;ym-=mark) { dr_move(ey0,ym);dr_draw(ey1+1,ym);}
  72.   dr_end();
  73.   dr_path();dr_move(ey0,0);dr_draw(ey1+1,0);dr_end();
  74.   for(x=ex0;x<=ex1;x++) if(width[x])
  75.   { eps+=.05;col++;dr_path();dr_style(mono?0:8+col%8,7,512);
  76.     for(y=ey0;y<=ey1;y++)
  77.     { cb=sheet[x+NCOLS*y];
  78.       if(cb&&cb->t>=FINT&&!(cb->p||cb->a))
  79.       { dr_move(y+eps,0);dr_draw(y+eps,cb->v);
  80.         dr_draw(y+1-eps,cb->v);dr_draw(y+1-eps,0);
  81.         dr_close();
  82.       }
  83.     }
  84.     dr_end();
  85.   }
  86.   for(ym=0;ym<=ymax;ym+=mark) ylab(-.1,ym);
  87.   for(ym=-mark;ym>=ymin;ym-=mark) ylab(-.1,ym);
  88.   if((sx0==sx1)&&(sy0==ey0))
  89.   { if(sy1==ey1) for(x=sy0;x<=sy1;x++) if(cellpr(sx0,x)) dr_printu(x+.5,ymin,num);
  90.   }
  91.   if(!dr_ok) return FALSE;
  92.   return dr_save(fn);
  93. }
  94.  
  95. static void cross(double x,double y,int k)
  96. { double cxsize=dr_xinch*.05,cysize=dr_yinch*.05;
  97.   dr_move(x-cxsize,y-cysize);dr_draw(x+cxsize,y+cysize);
  98.   dr_move(x+cxsize,y-cysize);dr_draw(x-cxsize,y+cysize);
  99.   if(k&1){ dr_move(x,y-cysize);dr_draw(x,y+cysize);}
  100.   if(k&2){ dr_move(x-cxsize,y);dr_draw(x+cxsize,y);}
  101. }
  102.  
  103. static void dots()
  104. { int x,y,c=0;
  105.   entry *ye;
  106.   for(y=ex0;y<=ex1;y++) if(width[y])
  107.   { dr_path();dr_style(-1,mono?7:8+c%8,512);c++;
  108.     for(x=sy0;x<=sy1;x++)
  109.     { ye=sheet[y+NCOLS*x];
  110.       if(ye&&ye->t>=FINT&&!(ye->p||ye->a))
  111.         cross(sheet[sx0+NCOLS*x]->v,ye->v,mono?c+2:3);
  112.     }
  113.     dr_end();
  114.   }
  115. }
  116.  
  117. static void lines()
  118. { int x,y,c=1;
  119.   int seen=0;
  120.   double startx,starty;
  121.   entry *ye;
  122.   for(y=ex0;y<=ex1;y++) if(width[y])
  123.   { dr_path();dr_style(-1,mono?7:8+(c++)%8,512);
  124.     seen=0;
  125.     for(x=sy0;x<=sy1;x++)
  126.     { ye=sheet[y+NCOLS*x];
  127.       if(ye&&ye->t>=FINT&&!(ye->p||ye->a))
  128.       switch(seen)
  129.       { case 0:seen=1;startx=sheet[sx0+NCOLS*x]->v;starty=ye->v;break;
  130.         case 1:seen=2;dr_move(startx,starty);
  131.         case 2:dr_draw(sheet[sx0+NCOLS*x]->v,ye->v);
  132.       }
  133.       else seen=0;
  134.     }
  135.     dr_end();
  136.   }
  137. }
  138.  
  139. BOOL graph_line(char *fn,void *v)
  140. { int x,y;
  141.   double xmin=0,ymin=0,xmax=0,ymax=0;
  142.   double xmark,ymark,m;
  143.   double xedge,yedge;
  144.   entry *cb;
  145.   if((sx0!=sx1)||(sy0!=ey0)||(sy1!=ey1)) return FALSE;
  146.   for(x=ex0;x<=ex1;x++) for(y=ey0;y<=ey1;y++)
  147.   { cb=sheet[x+NCOLS*y];
  148.     if(cb&&cb->t>=FINT&&!(cb->p||cb->a))
  149.     { if(cb->v<ymin) ymin=cb->v;
  150.       if(cb->v>ymax) ymax=cb->v;
  151.     }
  152.   }
  153.   for(y=sy0;y<=sy1;y++)
  154.   { cb=sheet[sx0+NCOLS*y];
  155.     if(!(cb&&cb->t>=FINT&&!(cb->p||cb->a))) return FALSE;
  156.     { if(cb->v<xmin) xmin=cb->v;
  157.       if(cb->v>xmax) xmax=cb->v;
  158.     }
  159.   }
  160.   if(xmax<=xmin) xmax+=1;
  161.   xedge=(xmax-xmin)*.125;
  162.   xmark=marksize((xmax-xmin)/6);
  163.   if(ymax<=ymin) ymax+=1;
  164.   yedge=(ymax-ymin)*.125;
  165.   dr_start(&dfile);
  166.   dr_scale(xmin-xedge,ymin-yedge,xmax+xedge,ymax+yedge);
  167.   dr_psize(xedge/(width[ex0]+1));
  168.   ymark=marksize((ymax-ymin)/6);
  169.   dr_path();
  170.   for(m=0;m<=ymax;m+=ymark) { dr_move(xmin,m);dr_draw(xmax,m);}
  171.   for(m=-ymark;m>=ymin;m-=ymark) { dr_move(xmin,m);dr_draw(xmax,m);}
  172.   dr_end();
  173.   for(m=0;m<=ymax;m+=ymark) ylab(xmin-xedge/10,m);
  174.   for(m=-ymark;m>=ymin;m-=ymark) ylab(xmin-xedge/10,m);
  175.   dr_path();
  176.   for(m=0;m<=xmax;m+=xmark) { dr_move(m,ymin);dr_draw(m,ymax);}
  177.   for(m=-xmark;m>=xmin;m-=xmark) { dr_move(m,ymin);dr_draw(m,ymax);}
  178.   dr_end();
  179.   for(m=0;m<=xmax;m+=xmark) xlab(m,ymin);
  180.   for(m=-xmark;m>=xmin;m-=xmark) xlab(m,ymin);
  181.   if(v) dots();else lines();
  182.   if(!dr_ok) return FALSE;
  183.   return dr_save(fn);
  184. }
  185.