/*
* gfio - gui front end for fio - the flexible io tester
*
- * Copyright (C) 2012 Stephen M. Cameron <stephenmcameron@gmail.com>
+ * Copyright (C) 2012 Stephen M. Cameron <stephenmcameron@gmail.com>
*
* The license below covers all files distributed with fio unless otherwise
* noted in the file itself.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include <string.h>
-#include <malloc.h>
+#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <stdlib.h>
#include "graph.h"
#include "flist.h"
#include "lib/prio_tree.h"
+#include "cairo_text_helpers.h"
/*
* Allowable difference to show tooltip
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 bottom_extra;
+ double left_extra;
+ double right_extra;
+ double top_extra;
+ double bottom_extra;
double xtick_zero;
double xtick_delta;
static double find_double_values(struct graph_label *l, double_comparator cmp)
{
struct flist_head *entry;
- double answer, tmp;
+ double answer = 0.0, tmp;
int first = 1;
if (flist_empty(&l->value_list))
cairo_close_path(cr);
cairo_fill(cr);
cairo_stroke(cr);
- bar_num++;
+ bar_num++;
}
}
-static void draw_aligned_text(struct graph *g, cairo_t *cr, double x, double y,
- double fontsize, const char *text, int alignment)
+static void graph_draw_common(struct graph *g, cairo_t *cr, double *x1,
+ double *y1, double *x2, double *y2)
{
-#define CENTERED 0
-#define LEFT_JUSTIFIED 1
-#define RIGHT_JUSTIFIED 2
+ const double shade_col[3][3] = { { 0.55, 0.54, 0.54 },
+ { 0.80, 0.78, 0.78 },
+ { 0.93, 0.91, 0.91 } };
+ int i;
- double factor, direction;
- cairo_text_extents_t extents;
+ *x1 = 0.10 * g->xdim;
+ *x2 = 0.95 * g->xdim;
+ *y1 = 0.10 * g->ydim;
+ *y2 = 0.90 * g->ydim;
- switch(alignment) {
- case CENTERED:
- direction = -1.0;
- factor = 0.5;
- break;
- case RIGHT_JUSTIFIED:
- direction = -1.0;
- factor = 1.0;
- break;
- case LEFT_JUSTIFIED:
- default:
- direction = 1.0;
- factor = 1.0;
- break;
+ /*
+ * Add shade
+ */
+ cairo_set_line_width(cr, 1.0);
+ for (i = 0; i < 3; i++) {
+ float offset = i + 1.0;
+
+ cairo_set_source_rgb(cr, shade_col[i][0], shade_col[i][1], shade_col[i][2]);
+ cairo_move_to(cr, offset + *x1, *y1 - offset);
+ cairo_line_to(cr, *x2 + offset, *y1 - offset);
+ cairo_line_to(cr, *x2 + offset, *y2 - offset);
+ cairo_stroke(cr);
}
- 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);
- x = x + direction * (factor * extents.width + extents.x_bearing);
- y = y - (extents.height / 2 + extents.y_bearing);
-
- cairo_move_to(cr, x, y);
- cairo_show_text(cr, text);
-}
-
-static inline void draw_centered_text(struct graph *g, cairo_t *cr, double x, double y,
- double fontsize, const char *text)
-{
- draw_aligned_text(g, cr, x, y, fontsize, text, CENTERED);
-}
-
-static inline void draw_right_justified_text(struct graph *g, cairo_t *cr,
- double x, double y,
- double fontsize, const char *text)
-{
- draw_aligned_text(g, cr, x, y, fontsize, text, RIGHT_JUSTIFIED);
-}
-
-static inline void draw_left_justified_text(struct graph *g, cairo_t *cr,
- double x, double y,
- double fontsize, const char *text)
-{
- draw_aligned_text(g, cr, x, y, fontsize, text, LEFT_JUSTIFIED);
-}
-
-static void draw_vertical_centered_text(struct graph *g, cairo_t *cr, double x,
- double y, double fontsize,
- const char *text)
-{
- double sx, sy;
- cairo_text_extents_t extents;
-
- 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);
- sx = x;
- sy = y;
- y = y + (extents.width / 2.0 + extents.x_bearing);
- x = x - (extents.height / 2.0 + extents.y_bearing);
-
- cairo_move_to(cr, x, y);
- cairo_save(cr);
- cairo_translate(cr, -sx, -sy);
- cairo_rotate(cr, -90.0 * M_PI / 180.0);
- cairo_translate(cr, sx, sy);
- cairo_show_text(cr, text);
- cairo_restore(cr);
-}
-
-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);
-
- *x1 = 0.10 * g->xdim;
- *x2 = 0.95 * g->xdim;
- *y1 = 0.10 * g->ydim;
- *y2 = 0.90 * g->ydim;
+ cairo_set_line_width(cr, 1.2);
cairo_move_to(cr, *x1, *y1);
cairo_line_to(cr, *x1, *y2);
cairo_line_to(cr, *x1, *y1);
cairo_stroke(cr);
- draw_centered_text(g, cr, g->xdim / 2, g->ydim / 20, 20.0, g->title);
- draw_centered_text(g, cr, g->xdim / 2, g->ydim * 0.97, 14.0, g->xtitle);
- draw_vertical_centered_text(g, cr, g->xdim * 0.02, g->ydim / 2, 14.0, g->ytitle);
+ draw_centered_text(cr, g->font, g->xdim / 2, g->ydim / 20, 20.0, g->title);
+ draw_centered_text(cr, g->font, g->xdim / 2, g->ydim * 0.97, 14.0, g->xtitle);
+ draw_vertical_centered_text(cr, g->font, g->xdim * 0.02, g->ydim / 2, 14.0, g->ytitle);
cairo_stroke(cr);
}
continue;
/* Draw tick mark */
- cairo_set_line_width(cr, 0.8);
+ cairo_set_line_width(cr, 1.0);
cairo_move_to(cr, tx, y2);
cairo_line_to(cr, tx, y2 + (y2 - y1) * 0.03);
cairo_stroke(cr);
/* draw grid lines */
cairo_save(cr);
- cairo_set_dash(cr, dash, 2, 2.0);
- cairo_set_line_width(cr, 0.5);
+ cairo_set_dash(cr, dash, 2, 0.66);
+ cairo_set_line_width(cr, 0.33);
cairo_move_to(cr, tx, y1);
cairo_line_to(cr, tx, y2);
cairo_stroke(cr);
continue;
/* draw tickmark label */
- draw_centered_text(g, cr, tx, y2 * 1.04, 12.0, tm[i].string);
+ draw_centered_text(cr, g->font, tx, y2 * 1.04, 12.0, tm[i].string);
cairo_stroke(cr);
}
}
struct tickmark *tm;
double ty;
int i, power_of_ten;
- static double dash[] = { 2.0, 2.0 };
+ static double dash[] = { 1.0, 2.0 };
nticks = calc_tickmarks(miny, maxy, nticks, &tm, &power_of_ten,
g->y_axis_unit_change_callback == NULL, g->base_offset);
/* draw grid lines */
cairo_save(cr);
- cairo_set_dash(cr, dash, 2, 2.0);
- cairo_set_line_width(cr, 0.5);
+ cairo_set_dash(cr, dash, 2, 0.66);
+ cairo_set_line_width(cr, 0.33);
cairo_move_to(cr, x1, ty);
cairo_line_to(cr, x2, ty);
cairo_stroke(cr);
continue;
/* draw tickmark label */
- draw_right_justified_text(g, cr, x1 - (x2 - x1) * 0.025, ty, 12.0, tm[i].string);
+ draw_right_justified_text(cr, g->font, x1 - (x2 - x1) * 0.025, ty, 12.0, tm[i].string);
cairo_stroke(cr);
}
maxdata = find_max_data(bg);
if (fabs(maxdata - mindata) < 1e-20) {
- draw_centered_text(bg, cr,
+ draw_centered_text(cr, bg->font,
x1 + (x2 - x1) / 2.0,
y1 + (y2 - y1) / 2.0, 20.0, "No good data");
return;
label_offset = bg->xdim * 0.1 + space_per_label * (double) i + space_per_label * 0.1;
draw_bars(bg, cr, lb, label_offset, bar_width, mindata, maxdata);
// draw_centered_text(cr, label_offset + (bar_width / 2.0 + bar_width * 0.1), bg->ydim * 0.93,
- draw_centered_text(bg, cr, x1 + space_per_label * (i + 0.5), bg->ydim * 0.93,
- 12.0, lb->label);
+ draw_centered_text(cr, bg->font, x1 + space_per_label * (i + 0.5), bg->ydim * 0.93,
+ 12.0, lb->label);
i++;
}
cairo_stroke(cr);
first = 0;
answer = tmp;
}
- answer = cmp(tmp, answer);
+ answer = cmp(tmp, answer);
}
}
goto skip_data;
cairo_set_line_width(cr, 1.5);
+ cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
+
flist_for_each(lentry, &g->label_list) {
i = flist_entry(lentry, struct graph_label, list);
first = 1;
if (first) {
cairo_move_to(cr, tx, ty);
first = 0;
- } else {
+ } else
cairo_line_to(cr, tx, ty);
- }
}
cairo_stroke(cr);
}
{
struct flist_head *entry;
struct graph_label *i;
-
+
flist_for_each(entry, &bg->label_list) {
i = flist_entry(entry, struct graph_label, list);
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 i; /* already present. */
*/
while (!(v->flags & GV_F_ON_PRIO)) {
assert(!flist_empty(&v->alias));
- v = flist_entry(v->alias.next, struct graph_value, alias);
+ v = flist_first_entry(&v->alias, struct graph_value, alias);
}
prio_tree_remove(&l->prio_tree, &v->node);
while (!flist_empty(&v->alias)) {
struct graph_value *a;
- a = flist_entry(v->alias.next, struct graph_value, alias);
+ a = flist_first_entry(&v->alias, struct graph_value, alias);
flist_del_init(&a->alias);
__graph_value_drop(l, a);
to_drop = 2;
while (to_drop-- && !flist_empty(&i->value_list)) {
- x = flist_entry(i->value_list.next, struct graph_value, list);
+ x = flist_first_entry(&i->value_list, struct graph_value, list);
graph_value_drop(i, x);
/*
struct graph_value *i;
while (!flist_empty(&l->value_list)) {
- i = flist_entry(l->value_list.next, struct graph_value, list);
+ i = flist_first_entry(&l->value_list, struct graph_value, list);
graph_value_drop(l, i);
- }
+ }
}
static void graph_free_labels(struct graph *g)
struct graph_label *i;
while (!flist_empty(&g->label_list)) {
- i = flist_entry(g->label_list.next, struct graph_label, list);
+ i = flist_first_entry(&g->label_list, struct graph_label, list);
flist_del(&i->list);
graph_free_values(i);
free(i);
- }
+ }
+}
+
+void graph_clear_values(struct graph *g)
+{
+ struct flist_head *node;
+ struct graph_label *i;
+
+ flist_for_each(node, &g->label_list) {
+ i = flist_entry(node, struct graph_label, list);
+ graph_free_values(i);
+ }
}
void graph_set_color(struct graph *gr, graph_label_t label, double red,
g->per_label_limit = per_label_limit;
}
-void graph_add_extra_space(struct graph *g, double left_percent, double right_percent,
- double top_percent, double bottom_percent)
+void graph_add_extra_space(struct graph *g, double left_percent,
+ double right_percent, double top_percent,
+ double bottom_percent)
{
- g->left_extra = left_percent;
- g->right_extra = right_percent;
- g->top_extra = top_percent;
- g->bottom_extra = bottom_percent;
+ g->left_extra = left_percent;
+ g->right_extra = right_percent;
+ g->top_extra = top_percent;
+ g->bottom_extra = bottom_percent;
}
/*
ydiff = fabs(yval - y);
/*
- * zero delta, or within or match critera, break
+ * zero delta, or within or match criteria, break
*/
if (ydiff < best_delta) {
best_delta = ydiff;
}
}
if (!flist_empty(&v->alias))
- v = flist_entry(v->alias.next, struct graph_value, alias);
+ v = flist_first_entry(&v->alias, struct graph_value, alias);
} while (v != rootv);
} while ((n = prio_tree_next(&iter)) != NULL);