gfio: hide graph if all values are zero

If all visible data points in a label are zero, don't display it
and don't show tooltips.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/gfio.c b/gfio.c
index 274dea8..3a0aa8f 100644
--- a/gfio.c
+++ b/gfio.c
@@ -88,6 +88,7 @@
 	graph_set_color(g, "Write IOPS", 1.0, 0.0, 0.0);
 	line_graph_set_data_count_limit(g, gfio_graph_limit);
 	graph_add_extra_space(g, 0.0, 0.0, 0.0, 0.0);
+	graph_set_graph_all_zeroes(g, 0);
 	return g;
 }
 
@@ -105,6 +106,7 @@
 	graph_set_base_offset(g, 1);
 	line_graph_set_data_count_limit(g, 100);
 	graph_add_extra_space(g, 0.0, 0.0, 0.0, 0.0);
+	graph_set_graph_all_zeroes(g, 0);
 	return g;
 }
 
diff --git a/graph.c b/graph.c
index 25e04ee..c543171 100644
--- a/graph.c
+++ b/graph.c
@@ -62,6 +62,7 @@
 	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 +84,7 @@
 	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;	
@@ -174,8 +176,9 @@
 	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 +201,9 @@
 	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);
@@ -573,7 +577,7 @@
 	}
 
 	return answer;
-} 
+}
 
 void line_graph_draw(struct graph *g, cairo_t *cr)
 {
@@ -640,7 +644,7 @@
 	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);
@@ -843,20 +847,40 @@
 	return 0;
 }
 
+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, const char *label,
 		      const double x, const double y, const char *tooltip)
 {
 	struct graph_label *i;
 	struct xyvalue *xy;
 
-	xy = malloc(sizeof(*xy));
-	xy->x = x;
-	xy->y = y;
-
 	i = graph_find_label(bg, label);
 	if (!i)
 		return -1;
 
+	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;
+
 	graph_label_add_value(i, xy, tooltip);
 	return 0;
 }
@@ -1004,6 +1028,8 @@
 		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 +1076,8 @@
 
 	return NULL;
 }
+
+void graph_set_graph_all_zeroes(struct graph *g, unsigned int set)
+{
+	g->dont_graph_all_zeroes = !set;
+}
diff --git a/graph.h b/graph.h
index 0099525..2315045 100644
--- a/graph.h
+++ b/graph.h
@@ -86,6 +86,7 @@
 extern int graph_contains_xy(struct graph *p, int x, int y);
 
 extern void graph_set_base_offset(struct graph *g, unsigned int base_offset);
+extern void graph_set_graph_all_zeroes(struct graph *g, unsigned int set);
 
 #endif