URI:
       tgraph.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tgraph.c (4187B)
       ---
            1 #include "stdinc.h"
            2 #include "dat.h"
            3 #include "fns.h"
            4 
            5 enum
            6 {
            7         Top = 1,
            8         Bottom = 1,
            9         Left = 40,
           10         Right = 0,
           11         MinWidth = Left+Right+2,
           12         MinHeight = Top+Bottom+2,
           13         DefaultWidth = Left+Right+500,
           14         DefaultHeight = Top+Bottom+40
           15 };
           16 
           17 QLock memdrawlock;
           18 static Memsubfont *smallfont;
           19 static Memimage *black;
           20 static Memimage *blue;
           21 static Memimage *red;
           22 static Memimage *lofill[6];
           23 static Memimage *hifill[6];
           24 static Memimage *grid;
           25 
           26 static ulong fill[] = {
           27         0xFFAAAAFF,        0xBB5D5DFF,        /* peach */
           28         DPalegreygreen, DPurpleblue,        /* aqua */
           29         DDarkyellow, DYellowgreen,        /* yellow */
           30         DMedgreen, DDarkgreen,                /* green */
           31         0x00AAFFFF, 0x0088CCFF,        /* blue */
           32         0xCCCCCCFF, 0x888888FF,        /* grey */
           33 };
           34 
           35 Memimage*
           36 allocrepl(ulong color)
           37 {
           38         Memimage *m;
           39 
           40         m = allocmemimage(Rect(0,0,1,1), RGB24);
           41         memfillcolor(m, color);
           42         m->flags |= Frepl;
           43         m->clipr = Rect(-1000000, -1000000, 1000000, 1000000);
           44         return m;
           45 }
           46 
           47 static void
           48 ginit(void)
           49 {
           50         static int first = 1;
           51         int i;
           52 
           53         if(!first)
           54                 return;
           55 
           56         first = 0;
           57         memimageinit();
           58 #ifdef PLAN9PORT
           59         smallfont = openmemsubfont(unsharp("#9/font/lucsans/lstr.10"));
           60 #else
           61         smallfont = openmemsubfont("/lib/font/bit/lucidasans/lstr.10");
           62 #endif
           63         black = memblack;
           64         blue = allocrepl(DBlue);
           65         red = allocrepl(DRed);
           66         grid = allocrepl(0x77777777);
           67         for(i=0; i<nelem(fill)/2 && i<nelem(lofill) && i<nelem(hifill); i++){
           68                 lofill[i] = allocrepl(fill[2*i]);
           69                 hifill[i] = allocrepl(fill[2*i+1]);
           70         }
           71 }
           72 
           73 static void
           74 mklabel(char *str, int v)
           75 {
           76         if(v < 0){
           77                 v = -v;
           78                 *str++ = '-';
           79         }
           80         if(v < 10000)
           81                 sprint(str, "%d", v);
           82         else if(v < 10000000)
           83                 sprint(str, "%dk", v/1000);
           84         else
           85                 sprint(str, "%dM", v/1000000);
           86 }
           87 
           88 static void
           89 drawlabel(Memimage *m, Point p, int n)
           90 {
           91         char buf[30];
           92         Point w;
           93 
           94         mklabel(buf, n);
           95         w = memsubfontwidth(smallfont, buf);
           96         memimagestring(m, Pt(p.x-5-w.x, p.y), memblack, ZP, smallfont, buf);
           97 }
           98 
           99 static int
          100 scalept(int val, int valmin, int valmax, int ptmin, int ptmax)
          101 {
          102         if(val <= valmin)
          103                 val = valmin;
          104         if(val >= valmax)
          105                 val = valmax;
          106         if(valmax == valmin)
          107                 valmax++;
          108         return ptmin + (vlong)(val-valmin)*(ptmax-ptmin)/(valmax-valmin);
          109 }
          110 
          111 Memimage*
          112 statgraph(Graph *g)
          113 {
          114         int i, nbin, x, lo, hi, min, max, first;
          115         Memimage *m;
          116         Rectangle r;
          117         Statbin *b, bin[2000];        /* 32 kB, but whack is worse */
          118 
          119         needstack(8192);        /* double check that bin didn't kill us */
          120 
          121         if(g->wid <= MinWidth)
          122                 g->wid = DefaultWidth;
          123         if(g->ht <= MinHeight)
          124                 g->ht = DefaultHeight;
          125         if(g->wid > nelem(bin))
          126                 g->wid = nelem(bin);
          127         if(g->fill < 0)
          128                 g->fill = ((uint)(uintptr)g->arg>>8)%nelem(lofill);
          129         if(g->fill > nelem(lofill))
          130                 g->fill %= nelem(lofill);
          131 
          132         nbin = g->wid - (Left+Right);
          133         binstats(g->fn, g->arg, g->t0, g->t1, bin, nbin);
          134 
          135         /*
          136          * compute bounds
          137          */
          138         min = g->min;
          139         max = g->max;
          140         if(min < 0 || max <= min){
          141                 min = max = 0;
          142                 first = 1;
          143                 for(i=0; i<nbin; i++){
          144                         b = &bin[i];
          145                         if(b->nsamp == 0)
          146                                 continue;
          147                         if(first || b->min < min)
          148                                 min = b->min;
          149                         if(first || b->max > max)
          150                                 max = b->max;
          151                         first = 0;
          152                 }
          153         }
          154 
          155         qlock(&memdrawlock);
          156         ginit();
          157         if(smallfont==nil || black==nil || blue==nil || red==nil || hifill[0]==nil || lofill[0]==nil){
          158                 werrstr("graphics initialization failed: %r");
          159                 qunlock(&memdrawlock);
          160                 return nil;
          161         }
          162 
          163         /* fresh image */
          164         m = allocmemimage(Rect(0,0,g->wid,g->ht), ABGR32);
          165         if(m == nil){
          166                 qunlock(&memdrawlock);
          167                 return nil;
          168         }
          169         r = Rect(Left, Top, g->wid-Right, g->ht-Bottom);
          170         memfillcolor(m, DTransparent);
          171 
          172         /* x axis */
          173         memimagedraw(m, Rect(r.min.x, r.max.y, r.max.x, r.max.y+1), black, ZP, memopaque, ZP, S);
          174 
          175         /* y labels */
          176         drawlabel(m, r.min, max);
          177         if(min != 0)
          178                 drawlabel(m, Pt(r.min.x, r.max.y-smallfont->height), min);
          179 
          180         /* actual data */
          181         for(i=0; i<nbin; i++){
          182                 b = &bin[i];
          183                 if(b->nsamp == 0)
          184                         continue;
          185                 lo = scalept(b->min, min, max, r.max.y, r.min.y);
          186                 hi = scalept(b->max, min, max, r.max.y, r.min.y);
          187                 x = r.min.x+i;
          188                 hi-=2;
          189                 memimagedraw(m, Rect(x, hi, x+1,lo), hifill[g->fill%nelem(hifill)], ZP, memopaque, ZP, S);
          190                 memimagedraw(m, Rect(x, lo, x+1, r.max.y), lofill[g->fill%nelem(lofill)], ZP, memopaque, ZP, S);
          191         }
          192 
          193         if(bin[nbin-1].nsamp)
          194                 drawlabel(m, Pt(r.max.x, r.min.y+(Dy(r)-smallfont->height)/2), bin[nbin-1].avg);
          195         qunlock(&memdrawlock);
          196         return m;
          197 }