123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- #include "stdinc.h"
- #include "dat.h"
- #include "fns.h"
- enum
- {
- Top = 1,
- Bottom = 1,
- Left = 40,
- Right = 0,
- MinWidth = Left+Right+2,
- MinHeight = Top+Bottom+2,
- DefaultWidth = Left+Right+500,
- DefaultHeight = Top+Bottom+40
- };
- QLock memdrawlock;
- static Memsubfont *smallfont;
- static Memimage *black;
- static Memimage *blue;
- static Memimage *red;
- static Memimage *lofill[6];
- static Memimage *hifill[6];
- static Memimage *grid;
- static ulong fill[] = {
- 0xFFAAAAFF, 0xBB5D5DFF, /* peach */
- DPalegreygreen, DPurpleblue, /* aqua */
- DDarkyellow, DYellowgreen, /* yellow */
- DMedgreen, DDarkgreen, /* green */
- 0x00AAFFFF, 0x0088CCFF, /* blue */
- 0xCCCCCCFF, 0x888888FF, /* grey */
- };
- Memimage*
- allocrepl(ulong color)
- {
- Memimage *m;
-
- m = allocmemimage(Rect(0,0,1,1), RGB24);
- memfillcolor(m, color);
- m->flags |= Frepl;
- m->clipr = Rect(-1000000, -1000000, 1000000, 1000000);
- return m;
- }
- static void
- ginit(void)
- {
- static int first = 1;
- int i;
-
- if(!first)
- return;
-
- first = 0;
- memimageinit();
- #ifdef PLAN9PORT
- smallfont = openmemsubfont(unsharp("#9/font/lucsans/lstr.10"));
- #else
- smallfont = openmemsubfont("/lib/font/bit/lucidasans/lstr.10");
- #endif
- black = memblack;
- blue = allocrepl(DBlue);
- red = allocrepl(DRed);
- grid = allocrepl(0x77777777);
- for(i=0; i<nelem(fill)/2 && i<nelem(lofill) && i<nelem(hifill); i++){
- lofill[i] = allocrepl(fill[2*i]);
- hifill[i] = allocrepl(fill[2*i+1]);
- }
- }
- static void
- mklabel(char *str, int v)
- {
- if(v < 0){
- v = -v;
- *str++ = '-';
- }
- if(v < 10000)
- sprint(str, "%d", v);
- else if(v < 10000000)
- sprint(str, "%dk", v/1000);
- else
- sprint(str, "%dM", v/1000000);
- }
- static void
- drawlabel(Memimage *m, Point p, int n)
- {
- char buf[30];
- Point w;
-
- mklabel(buf, n);
- w = memsubfontwidth(smallfont, buf);
- memimagestring(m, Pt(p.x-5-w.x, p.y), memblack, ZP, smallfont, buf);
- }
- static int
- scalept(int val, int valmin, int valmax, int ptmin, int ptmax)
- {
- if(val <= valmin)
- val = valmin;
- if(val >= valmax)
- val = valmax;
- if(valmax == valmin)
- valmax++;
- return ptmin + (vlong)(val-valmin)*(ptmax-ptmin)/(valmax-valmin);
- }
- Memimage*
- statgraph(Graph *g)
- {
- int i, nbin, x, lo, hi, min, max, first;
- Memimage *m;
- Rectangle r;
- Statbin *b, bin[2000]; /* 32 kB, but whack is worse */
- needstack(8192); /* double check that bin didn't kill us */
-
- if(g->wid <= MinWidth)
- g->wid = DefaultWidth;
- if(g->ht <= MinHeight)
- g->ht = DefaultHeight;
- if(g->wid > nelem(bin))
- g->wid = nelem(bin);
- if(g->fill < 0)
- g->fill = ((uint)(uintptr)g->arg>>8)%nelem(lofill);
- if(g->fill > nelem(lofill))
- g->fill %= nelem(lofill);
-
- nbin = g->wid - (Left+Right);
- binstats(g->fn, g->arg, g->t0, g->t1, bin, nbin);
- /*
- * compute bounds
- */
- min = g->min;
- max = g->max;
- if(min < 0 || max <= min){
- min = max = 0;
- first = 1;
- for(i=0; i<nbin; i++){
- b = &bin[i];
- if(b->nsamp == 0)
- continue;
- if(first || b->min < min)
- min = b->min;
- if(first || b->max > max)
- max = b->max;
- first = 0;
- }
- }
- qlock(&memdrawlock);
- ginit();
- if(smallfont==nil || black==nil || blue==nil || red==nil || hifill==nil || lofill==nil){
- werrstr("graphics initialization failed: %r");
- qunlock(&memdrawlock);
- return nil;
- }
- /* fresh image */
- m = allocmemimage(Rect(0,0,g->wid,g->ht), ABGR32);
- if(m == nil){
- qunlock(&memdrawlock);
- return nil;
- }
- r = Rect(Left, Top, g->wid-Right, g->ht-Bottom);
- memfillcolor(m, DTransparent);
-
- /* x axis */
- memimagedraw(m, Rect(r.min.x, r.max.y, r.max.x, r.max.y+1), black, ZP, memopaque, ZP, S);
- /* y labels */
- drawlabel(m, r.min, max);
- if(min != 0)
- drawlabel(m, Pt(r.min.x, r.max.y-smallfont->height), min);
-
- /* actual data */
- for(i=0; i<nbin; i++){
- b = &bin[i];
- if(b->nsamp == 0)
- continue;
- lo = scalept(b->min, min, max, r.max.y, r.min.y);
- hi = scalept(b->max, min, max, r.max.y, r.min.y);
- x = r.min.x+i;
- hi-=2;
- memimagedraw(m, Rect(x, hi, x+1,lo), hifill[g->fill%nelem(hifill)], ZP, memopaque, ZP, S);
- memimagedraw(m, Rect(x, lo, x+1, r.max.y), lofill[g->fill%nelem(lofill)], ZP, memopaque, ZP, S);
- }
- if(bin[nbin-1].nsamp)
- drawlabel(m, Pt(r.max.x, r.min.y+(Dy(r)-smallfont->height)/2), bin[nbin-1].avg);
- qunlock(&memdrawlock);
- return m;
- }
|