enum {
GV_F_ON_PRIO = 1,
+ GV_F_PRIO_SKIP = 2,
};
struct graph_value {
struct flist_head value_list;
struct prio_tree_root prio_tree;
double r, g, b;
+ int hide;
int value_count;
struct graph *parent;
};
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;
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;
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);
}
return answer;
-}
+}
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);
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)
{
- flist_del(&v->list);
+ flist_del_init(&v->list);
if (v->tooltip)
free(v->tooltip);
free(v->value);
static void graph_value_drop(struct graph_label *l, struct graph_value *v)
{
- struct flist_head *entry, *tmp;
+ if (v->flags & GV_F_PRIO_SKIP) {
+ __graph_value_drop(l, v);
+ return;
+ }
/*
* Find head, the guy that's on the prio tree
/*
* Free aliases
*/
- flist_for_each_safe(entry, tmp, &v->alias) {
+ while (!flist_empty(&v->alias)) {
struct graph_value *a;
- a = flist_entry(entry, struct graph_value, alias);
- flist_del(&a->alias);
+ a = flist_entry(v->alias.next, struct graph_value, alias);
+ flist_del_init(&a->alias);
__graph_value_drop(l, a);
}
alias = container_of(ret, struct graph_value, node);
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) {
}
}
-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;
}
}
}
-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 */
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)
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);
/*
* If we got matches in one label, don't check others.
*/
- break;
+ if (best)
+ break;
}
if (best)
return NULL;
}
+
+void graph_set_graph_all_zeroes(struct graph *g, unsigned int set)
+{
+ g->dont_graph_all_zeroes = !set;
+}