gfio: improve and remember font selection
[fio.git] / graph.c
diff --git a/graph.c b/graph.c
index 25e04eec5151a878f13ef96eca7aaad922d0df00..51eb3eff17cb1f5f4d99ee203ea3718f4c482774 100644 (file)
--- a/graph.c
+++ b/graph.c
@@ -45,6 +45,7 @@ struct xyvalue {
 
 enum {
        GV_F_ON_PRIO    = 1,
+       GV_F_PRIO_SKIP  = 2,
 };
 
 struct graph_value {
@@ -62,6 +63,7 @@ struct graph_label {
        struct flist_head value_list;
        struct prio_tree_root prio_tree;
        double r, g, b;
+       int hide;
        int value_count;
        struct graph *parent;
 };
@@ -83,6 +85,7 @@ struct graph {
        graph_axis_unit_change_callback x_axis_unit_change_callback;
        graph_axis_unit_change_callback y_axis_unit_change_callback;
        unsigned int base_offset;
+       unsigned int dont_graph_all_zeroes;
        double left_extra;      
        double right_extra;     
        double top_extra;       
@@ -120,10 +123,15 @@ struct graph *graph_new(unsigned int xdim, unsigned int ydim, const char *font)
        g->per_label_limit = -1;
        g->font = font;
        if (!g->font)
-               g->font = "Sans";
+               g->font = GRAPH_DEFAULT_FONT;
        return g;
 }
 
+void graph_set_font(struct graph *g, const char *font)
+{
+       g->font = font;
+}
+
 void graph_x_axis_unit_change_notify(struct graph *g, graph_axis_unit_change_callback f)
 {
        g->x_axis_unit_change_callback = f;
@@ -174,8 +182,9 @@ static double find_double_values(struct graph_label *l, double_comparator cmp)
        double answer, tmp;
        int first = 1;
 
-       assert(!flist_empty(&l->value_list));
-       answer = 0.0; /* shut the compiler up, might need to think harder though. */
+       if (flist_empty(&l->value_list))
+               return 0.0;
+
        flist_for_each(entry, &l->value_list) {
                struct graph_value *i;
 
@@ -198,8 +207,9 @@ static double find_double_data(struct graph *g, double_comparator cmp)
        int first = 1;
        double answer, tmp;
 
-       assert(!flist_empty(&g->label_list));
-       answer = 0.0; /* shut the compiler up, might need to think harder though. */
+       if (flist_empty(&g->label_list))
+               return 0.0;
+
        flist_for_each(entry, &g->label_list) {
                i = flist_entry(entry, struct graph_label, list);
                tmp = find_double_values(i, cmp);
@@ -281,7 +291,7 @@ static void draw_aligned_text(struct graph *g, cairo_t *cr, double x, double y,
                        factor = 1.0;
                        break;
        }
-       cairo_select_font_face (cr, g->font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+       cairo_select_font_face(cr, g->font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
 
        cairo_set_font_size(cr, fontsize);
        cairo_text_extents(cr, text, &extents);
@@ -340,8 +350,8 @@ static void draw_vertical_centered_text(struct graph *g, cairo_t *cr, double x,
 static void graph_draw_common(struct graph *g, cairo_t *cr,
        double *x1, double *y1, double *x2, double *y2)
 {
-        cairo_set_source_rgb(cr, 0, 0, 0);
-        cairo_set_line_width (cr, 0.8);
+       cairo_set_source_rgb(cr, 0, 0, 0);
+       cairo_set_line_width (cr, 0.8);
 
        *x1 = 0.10 * g->xdim;   
        *x2 = 0.95 * g->xdim;
@@ -573,7 +583,7 @@ static double find_xy_value(struct graph *g, xy_value_extractor getvalue, double
        }
 
        return answer;
-} 
+}
 
 void line_graph_draw(struct graph *g, cairo_t *cr)
 {
@@ -640,7 +650,7 @@ void line_graph_draw(struct graph *g, cairo_t *cr)
        flist_for_each(lentry, &g->label_list) {
                i = flist_entry(lentry, struct graph_label, list);
                first = 1;
-               if (i->r < 0) /* invisible data */
+               if (i->hide || i->r < 0) /* invisible data */
                        continue;
 
                cairo_set_source_rgb(cr, i->r, i->g, i->b);
@@ -699,19 +709,20 @@ static struct graph_label *graph_find_label(struct graph *bg,
        return NULL;
 }
 
-void graph_add_label(struct graph *bg, const char *label)
+graph_label_t graph_add_label(struct graph *bg, const char *label)
 {
        struct graph_label *i;
        
        i = graph_find_label(bg, label);
        if (i)
-               return; /* already present. */
+               return i; /* already present. */
        i = calloc(1, sizeof(*i));
        INIT_FLIST_HEAD(&i->value_list);
        i->parent = bg;
        setstring(&i->label, label);
        flist_add_tail(&i->list, &bg->label_list);
        INIT_PRIO_TREE_ROOT(&i->prio_tree);
+       return i;
 }
 
 static void __graph_value_drop(struct graph_label *l, struct graph_value *v)
@@ -726,6 +737,11 @@ static void __graph_value_drop(struct graph_label *l, struct graph_value *v)
 
 static void graph_value_drop(struct graph_label *l, struct graph_value *v)
 {
+       if (v->flags & GV_F_PRIO_SKIP) {
+               __graph_value_drop(l, v);
+               return;
+       }
+
        /*
         * Find head, the guy that's on the prio tree
         */
@@ -800,7 +816,8 @@ static void graph_label_add_value(struct graph_label *i, void *value,
                        flist_add_tail(&x->alias, &alias->alias);
                } else
                        x->flags = GV_F_ON_PRIO;
-       }
+       } else
+               x->flags = GV_F_PRIO_SKIP;
 
        if (g->per_label_limit != -1 &&
                i->value_count > g->per_label_limit) {
@@ -828,35 +845,48 @@ static void graph_label_add_value(struct graph_label *i, void *value,
        }
 }
 
-int graph_add_data(struct graph *bg, const char *label, const double value)
+int graph_add_data(struct graph *bg, graph_label_t label, const double value)
 {
-       struct graph_label *i;
+       struct graph_label *i = label;
        double *d;
 
        d = malloc(sizeof(*d));
        *d = value;
 
-       i = graph_find_label(bg, label);
-       if (!i)
-               return -1;
        graph_label_add_value(i, d, NULL);
        return 0;
 }
 
-int graph_add_xy_data(struct graph *bg, const char *label,
+static int graph_nonzero_y(struct graph_label *l)
+{
+       struct flist_head *entry;
+
+       flist_for_each(entry, &l->value_list) {
+               struct graph_value *v;
+
+               v = flist_entry(entry, struct graph_value, list);
+               if (gety(v) != 0.0)
+                       return 1;
+       }
+
+       return 0;
+}
+
+int graph_add_xy_data(struct graph *bg, graph_label_t label,
                      const double x, const double y, const char *tooltip)
 {
-       struct graph_label *i;
+       struct graph_label *i = label;
        struct xyvalue *xy;
 
+       if (bg->dont_graph_all_zeroes && y == 0.0 && !graph_nonzero_y(i))
+               i->hide = 1;
+       else
+               i->hide = 0;
+
        xy = malloc(sizeof(*xy));
        xy->x = x;
        xy->y = y;
 
-       i = graph_find_label(bg, label);
-       if (!i)
-               return -1;
-
        graph_label_add_value(i, xy, tooltip);
        return 0;
 }
@@ -883,11 +913,10 @@ static void graph_free_labels(struct graph *g)
        }       
 }
 
-void graph_set_color(struct graph *gr, const char *label,
-       double red, double green, double blue)
+void graph_set_color(struct graph *gr, graph_label_t label, double red,
+                    double green, double blue)
 {
-       struct flist_head *entry;
-       struct graph_label *i;
+       struct graph_label *i = label;
        double r, g, b;
 
        if (red < 0.0) { /* invisible color */
@@ -907,16 +936,9 @@ void graph_set_color(struct graph *gr, const char *label,
                        b = 1.0;
        }
 
-       flist_for_each(entry, &gr->label_list) {
-               i = flist_entry(entry, struct graph_label, list);
-
-               if (strcmp(i->label, label) == 0) {
-                       i->r = r;       
-                       i->g = g;       
-                       i->b = b;       
-                       break;
-               }
-       }
+       i->r = r;
+       i->g = g;
+       i->b = b;
 }
 
 void graph_free(struct graph *bg)
@@ -1004,6 +1026,8 @@ const char *graph_find_tooltip(struct graph *g, int ix, int iy)
                struct graph_label *i;
 
                i = flist_entry(entry, struct graph_label, list);
+               if (i->hide)
+                       continue;
 
                INIT_PRIO_TREE_ITER(&iter);
                prio_tree_iter_init(&iter, &i->prio_tree, x, x);
@@ -1050,3 +1074,8 @@ const char *graph_find_tooltip(struct graph *g, int ix, int iy)
 
        return NULL;
 }
+
+void graph_set_graph_all_zeroes(struct graph *g, unsigned int set)
+{
+       g->dont_graph_all_zeroes = !set;
+}