@@ -221,12 +221,16 @@ igt_vector_t *igt_vector_linear(double min, double max, unsigned int n)
}
static void igt_plot_axis_init(igt_plot_axis_t *axis,
- igt_orientation_t orientation)
+ igt_side_t side)
{
memset(axis, 0, sizeof(*axis));
axis->n_ticks = 5;
- axis->orientation = orientation;
+ axis->side = side;
+ if (side == IGT_SIDE_TOP || side == IGT_SIDE_BOTTOM)
+ axis->orientation = IGT_ORIENTATION_HORIZONTAL;
+ else
+ axis->orientation = IGT_ORIENTATION_VERTICAL;
axis->min = DBL_MAX;
axis->max = -DBL_MAX;
}
@@ -280,8 +284,10 @@ void igt_plot_init(igt_plot_t *plot, unsigned int width, unsigned int height)
plot->height = height;
plot->cr = cairo_create(plot->surface);
- igt_plot_axis_init(&plot->x_axis, IGT_ORIENTATION_HORIZONTAL);
- igt_plot_axis_init(&plot->y_axis, IGT_ORIENTATION_VERTICAL);
+ igt_plot_axis_init(&plot->x_axis, IGT_SIDE_BOTTOM);
+ igt_plot_axis_init(&plot->y_axis, IGT_SIDE_LEFT);
+ igt_plot_axis_init(&plot->x_axis_top, IGT_SIDE_TOP);
+ igt_plot_axis_init(&plot->y_axis_right, IGT_SIDE_RIGHT);
plot->ctx = &plot->contexts[0];
igt_plot_ctx_init(plot->ctx);
@@ -501,6 +507,7 @@ static void igt_plot_draw_ticks(igt_plot_t *plot, igt_plot_axis_t *axis,
area_width = area->x2 - area->x1;
area_height = area->y2 - area->y1;
+ cairo_set_font_size(plot->cr, flush->tick_label_font_size);
cairo_set_line_cap(plot->cr, CAIRO_LINE_CAP_SQUARE);
cairo_set_line_width(plot->cr, 1.0);
@@ -508,7 +515,7 @@ static void igt_plot_draw_ticks(igt_plot_t *plot, igt_plot_axis_t *axis,
double x, y;
igt_label_t *label;
- if (axis->orientation == IGT_ORIENTATION_HORIZONTAL) {
+ if (axis->side == IGT_SIDE_BOTTOM) {
x = area->x1 + i * area_width / (axis->n_ticks - 1);
y = area->y2;
@@ -518,7 +525,8 @@ static void igt_plot_draw_ticks(igt_plot_t *plot, igt_plot_axis_t *axis,
label = &flush->x_tick_labels[i];
y += flush->tick_label_padding;
- } else {
+ igt_plot_draw_text(plot, x, y, label);
+ } else if (axis->side == IGT_SIDE_LEFT) {
x = area->x1;
y = area->y2 - i * area_height / (axis->n_ticks - 1);
@@ -528,10 +536,22 @@ static void igt_plot_draw_ticks(igt_plot_t *plot, igt_plot_axis_t *axis,
label = &flush->y_tick_labels[i];
x -= flush->tick_label_padding;
- }
+ igt_plot_draw_text(plot, x, y, label);
+ } else if (axis->side == IGT_SIDE_TOP) {
+ x = area->x1 + i * area_width / (axis->n_ticks - 1);
+ y = area->y1;
- cairo_set_font_size(plot->cr, flush->tick_label_font_size);
- igt_plot_draw_text(plot, x, y, label);
+ cairo_move_to(plot->cr, SNAP(x), y);
+ cairo_line_to(plot->cr, SNAP(x), SNAP(y + tick_length));
+ cairo_stroke(plot->cr);
+ } else {
+ x = area->x2;
+ y = area->y1 + i * area_height / (axis->n_ticks - 1);
+
+ cairo_move_to(plot->cr, x, SNAP(y));
+ cairo_line_to(plot->cr, SNAP(x - tick_length), SNAP(y));
+ cairo_stroke(plot->cr);
+ }
}
}
@@ -545,11 +565,19 @@ static void igt_plot_draw_axis(igt_plot_t *plot, flush_t *flush)
cairo_line_to(plot->cr, area->x2, area->y2);
igt_plot_draw_ticks(plot, &plot->x_axis, tick_length, flush);
+ cairo_move_to(plot->cr, area->x1, area->y1);
+ cairo_line_to(plot->cr, area->x2, area->y1);
+ igt_plot_draw_ticks(plot, &plot->x_axis_top, tick_length, flush);
+
/* Y-axis */
cairo_move_to(plot->cr, area->x1, area->y2);
cairo_line_to(plot->cr, area->x1, area->y1);
igt_plot_draw_ticks(plot, &plot->y_axis, tick_length, flush);
+ cairo_move_to(plot->cr, area->x2, area->y1);
+ cairo_line_to(plot->cr, area->x2, area->y2);
+ igt_plot_draw_ticks(plot, &plot->y_axis_right, tick_length, flush);
+
}
static void igt_plot_layout_tick_labels(igt_plot_t *plot,
@@ -74,6 +74,7 @@ void igt_vector_get_min_max(const igt_vector_t *v, double *min, double *max);
typedef struct {
/*< private >*/
igt_orientation_t orientation;
+ igt_side_t side;
unsigned int n_ticks;
double min, max; /* range of the values on this axis */
} igt_plot_axis_t;
@@ -104,6 +105,7 @@ typedef struct {
unsigned int width, height;
igt_trbl_t margin;
igt_plot_axis_t x_axis, y_axis;
+ igt_plot_axis_t x_axis_top, y_axis_right;
/* per draw command contexts */
igt_plot_ctx_t contexts[IGT_PLOT_MAX_PLOTS + 1];
@@ -66,6 +66,20 @@ typedef struct {
} igt_box_t;
/**
+ * igt_side_t:
+ * @IGT_SIDE_TOP: Top
+ * @IGT_SIDE_RIGHT: Right
+ * @IGT_SIDE_BOTTOM: Bottom
+ * @IGT_SIDE_LEFT: Left
+ */
+typedef enum {
+ IGT_SIDE_TOP,
+ IGT_SIDE_RIGHT,
+ IGT_SIDE_BOTTOM,
+ IGT_SIDE_LEFT,
+} igt_side_t;
+
+/**
* igt_trbl_t:
* @top: Top value
* @right: Right value
This frames a bit more the plot will look nice with a background grid. Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> --- lib/igt_plot.c | 46 +++++++++++++++++++++++++++++++++++++--------- lib/igt_plot.h | 2 ++ lib/igt_types.h | 14 ++++++++++++++ 3 files changed, 53 insertions(+), 9 deletions(-)