aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/venti/srv/graph.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-07-12 15:23:36 +0000
committerrsc <devnull@localhost>2005-07-12 15:23:36 +0000
commita0d146edd7a7de6236a0d60baafeeb59f8452aae (patch)
treeb55baa526d9f5adfc73246e6ee2fadf455e0b7a2 /src/cmd/venti/srv/graph.c
parent88bb285e3d87ec2508840af33f7e0af53ec3c13c (diff)
downloadplan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.tar.gz
plan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.tar.bz2
plan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.zip
return of venti
Diffstat (limited to 'src/cmd/venti/srv/graph.c')
-rw-r--r--src/cmd/venti/srv/graph.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/src/cmd/venti/srv/graph.c b/src/cmd/venti/srv/graph.c
new file mode 100644
index 00000000..157b82db
--- /dev/null
+++ b/src/cmd/venti/srv/graph.c
@@ -0,0 +1,202 @@
+#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();
+ smallfont = openmemsubfont(unsharp("#9/font/lucidasans/lstr.10"));
+ 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, lastlo, 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)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");
+ 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 */
+ lastlo = -1;
+ 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;
+ if(0)
+ if(lastlo != -1){
+ if(lastlo < lo)
+ memimagedraw(m, Rect(x-1, lastlo, x, lo), hifill[g->fill], ZP, memopaque, ZP, S);
+ else if(lastlo > lo)
+ memimagedraw(m, Rect(x-1, lo, x, lastlo), hifill[g->fill], ZP, memopaque, ZP, S);
+ }
+ memimagedraw(m, Rect(x, hi, x+1,lo), hifill[g->fill], ZP, memopaque, ZP, S);
+ memimagedraw(m, Rect(x, lo, x+1, r.max.y), lofill[g->fill], ZP, memopaque, ZP, S);
+ lastlo = lo;
+ }
+
+ 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;
+}