char *xtitle;
char *ytitle;
unsigned int xdim, ydim;
+ double xoffset, yoffset;
struct graph_label *labels;
struct graph_label *tail;
int per_label_limit;
const char *font;
+ graph_axis_unit_change_callback x_axis_unit_change_callback;
+ graph_axis_unit_change_callback y_axis_unit_change_callback;
};
void graph_set_size(struct graph *g, unsigned int xdim, unsigned int ydim)
g->ydim = ydim;
}
+void graph_set_position(struct graph *g, double xoffset, double yoffset)
+{
+ g->xoffset = xoffset;
+ g->yoffset = yoffset;
+}
+
struct graph *graph_new(unsigned int xdim, unsigned int ydim, const char *font)
{
struct graph *g;
return g;
}
+void graph_x_axis_unit_change_notify(struct graph *g, graph_axis_unit_change_callback f)
+{
+ g->x_axis_unit_change_callback = f;
+}
+
+void graph_y_axis_unit_change_notify(struct graph *g, graph_axis_unit_change_callback f)
+{
+ g->y_axis_unit_change_callback = f;
+}
+
static int count_labels(struct graph_label *labels)
{
int count = 0;
{
struct tickmark *tm;
double tx;
- int i;
+ int i, power_of_ten;
static double dash[] = { 1.0, 2.0 };
- nticks = calc_tickmarks(minx, maxx, nticks, &tm);
+ nticks = calc_tickmarks(minx, maxx, nticks, &tm, &power_of_ten,
+ g->x_axis_unit_change_callback == NULL);
+ if (g->x_axis_unit_change_callback)
+ g->x_axis_unit_change_callback(g, power_of_ten);
for (i = 0; i < nticks; i++) {
tx = (((tm[i].value) - minx) / (maxx - minx)) * (x2 - x1) + x1;
{
struct tickmark *tm;
double ty;
- int i;
+ int i, power_of_ten;
static double dash[] = { 2.0, 2.0 };
- nticks = calc_tickmarks(miny, maxy, nticks, &tm);
+ nticks = calc_tickmarks(miny, maxy, nticks, &tm, &power_of_ten,
+ g->y_axis_unit_change_callback == NULL);
+ if (g->y_axis_unit_change_callback)
+ g->y_axis_unit_change_callback(g, power_of_ten);
for (i = 0; i < nticks; i++) {
ty = y2 - (((tm[i].value) - miny) / (maxy - miny)) * (y2 - y1);
struct graph_label *lb;
cairo_save(cr);
+ cairo_translate(cr, bg->xoffset, bg->yoffset);
graph_draw_common(bg, cr, &x1, &y1, &x2, &y2);
nlabels = count_labels(bg->labels);
int good_data = 1, first = 1;
cairo_save(cr);
+ cairo_translate(cr, g->xoffset, g->yoffset);
graph_draw_common(g, cr, &x1, &y1, &x2, &y2);
minx = find_xy_value(g, getx, mindouble);
if (i->parent->per_label_limit != -1 &&
i->value_count > i->parent->per_label_limit) {
- x = i->values;
- i->values = i->values->next;
- free(x->value);
- free(x);
- i->value_count--;
+ int to_drop = 1;
+
+ /*
+ * If the limit was dynamically reduced, making us more
+ * than 1 entry ahead after adding this one, drop two
+ * entries. This will make us (eventually) reach the
+ * specified limit.
+ */
+ if (i->value_count - i->parent->per_label_limit >= 2)
+ to_drop = 2;
+
+ while (to_drop--) {
+ x = i->values;
+ i->values = i->values->next;
+ free(x->value);
+ free(x);
+ i->value_count--;
+ }
}
}