From: John Darrington Date: Sat, 24 Mar 2012 08:53:49 +0000 (+0100) Subject: cairo-chart.c: new struct xrchart_axis X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=084a3ed2450295a9f1ebfd30b9a93f1e3dac7bf1;p=pspp cairo-chart.c: new struct xrchart_axis This allows a bit of refactoring. --- diff --git a/src/output/cairo-chart.c b/src/output/cairo-chart.c index 3ec00ce9a5..070319a58e 100644 --- a/src/output/cairo-chart.c +++ b/src/output/cairo-chart.c @@ -47,10 +47,10 @@ xrchart_geometry_init (cairo_t *cr, struct xrchart_geometry *geom, double width, double length) { /* Set default chartetry. */ - geom->data_top = 0.900 * length; - geom->data_right = 0.800 * width; - geom->data_bottom = 0.120 * length; - geom->data_left = 0.150 * width; + geom->axis[SCALE_ORDINATE].data_max = 0.900 * length; + geom->axis[SCALE_ABSCISSA].data_max = 0.800 * width; + geom->axis[SCALE_ORDINATE].data_min = 0.120 * length; + geom->axis[SCALE_ABSCISSA].data_min = 0.150 * width; geom->abscissa_top = 0.070 * length; geom->ordinate_right = 0.120 * width; geom->title_bottom = 0.920 * length; @@ -67,9 +67,9 @@ xrchart_geometry_init (cairo_t *cr, struct xrchart_geometry *geom, cairo_set_line_width (cr, 1.0); - cairo_rectangle (cr, geom->data_left, geom->data_bottom, - geom->data_right - geom->data_left, - geom->data_top - geom->data_bottom); + cairo_rectangle (cr, geom->axis[SCALE_ABSCISSA].data_min, geom->axis[SCALE_ORDINATE].data_min, + geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ABSCISSA].data_min, + geom->axis[SCALE_ORDINATE].data_max - geom->axis[SCALE_ORDINATE].data_min); cairo_stroke (cr); } @@ -226,14 +226,14 @@ draw_tick (cairo_t *cr, const struct xrchart_geometry *geom, const int tickSize = 10; double x, y; - cairo_move_to (cr, geom->data_left, geom->data_bottom); + cairo_move_to (cr, geom->axis[SCALE_ABSCISSA].data_min, geom->axis[SCALE_ORDINATE].data_min); - if (orientation == TICK_ABSCISSA) + if (orientation == SCALE_ABSCISSA) { cairo_rel_move_to (cr, position, 0); cairo_rel_line_to (cr, 0, -tickSize); } - else if (orientation == TICK_ORDINATE) + else if (orientation == SCALE_ORDINATE) { cairo_rel_move_to (cr, 0, position); cairo_rel_line_to (cr, -tickSize, 0); @@ -253,9 +253,9 @@ draw_tick (cairo_t *cr, const struct xrchart_geometry *geom, va_start (ap, label); s = xvasprintf (label, ap); - if (orientation == TICK_ABSCISSA) + if (orientation == SCALE_ABSCISSA) xrchart_label (cr, 'c', 't', geom->font_size, s); - else if (orientation == TICK_ORDINATE) + else if (orientation == SCALE_ORDINATE) { if (fabs (position) < DBL_EPSILON) cairo_rel_move_to (cr, 0, 10); @@ -276,7 +276,7 @@ xrchart_write_title (cairo_t *cr, const struct xrchart_geometry *geom, char *s; cairo_save (cr); - cairo_move_to (cr, geom->data_left, geom->title_bottom); + cairo_move_to (cr, geom->axis[SCALE_ABSCISSA].data_min, geom->title_bottom); va_start(ap, title); s = xvasprintf (title, ap); @@ -288,55 +288,55 @@ xrchart_write_title (cairo_t *cr, const struct xrchart_geometry *geom, } -/* Set the scale for the abscissa */ -void -xrchart_write_xscale (cairo_t *cr, struct xrchart_geometry *geom, - double min, double max, int ticks) +/* Set the scale for the ordinate */ +static void +xrchart_write_scale (cairo_t *cr, struct xrchart_geometry *geom, + double smin, double smax, int ticks, enum tick_orientation orient) { - double x; + double y; const double tick_interval = - chart_rounded_tick ((max - min) / (double) ticks); + chart_rounded_tick ((smax - smin) / (double) ticks); - geom->x_max = ceil (max / tick_interval) * tick_interval; - geom->x_min = floor (min / tick_interval) * tick_interval; - geom->abscissa_scale = fabs(geom->data_right - geom->data_left) / - fabs(geom->x_max - geom->x_min); + geom->axis[orient].max = ceil (smax / tick_interval) * tick_interval; + geom->axis[orient].min = floor (smin / tick_interval) * tick_interval; - for (x = geom->x_min; x <= geom->x_max; x += tick_interval) - draw_tick (cr, geom, TICK_ABSCISSA, - (x - geom->x_min) * geom->abscissa_scale, "%g", x); -} + geom->axis[orient].scale = (fabs (geom->axis[orient].data_max - geom->axis[orient].data_min) + / fabs (geom->axis[orient].max - geom->axis[orient].min)); + /* + geom->axis[orient].scale = (fabs (geom->axis[SCALE_ORDINATE].data_max - geom->axis[SCALE_ORDINATE].data_min) + / fabs (geom->axis[orient].max - geom->axis[orient].min)); + */ + + + for (y = geom->axis[orient].min; y <= geom->axis[orient].max; y += tick_interval) + draw_tick (cr, geom, orient, + (y - geom->axis[orient].min) * geom->axis[orient].scale, "%g", y); +} -/* Set the scale for the ordinate */ void xrchart_write_yscale (cairo_t *cr, struct xrchart_geometry *geom, double smin, double smax, int ticks) { - double y; - - const double tick_interval = - chart_rounded_tick ((smax - smin) / (double) ticks); - - geom->y_max = ceil (smax / tick_interval) * tick_interval; - geom->y_min = floor (smin / tick_interval) * tick_interval; - - geom->ordinate_scale = - (fabs (geom->data_top - geom->data_bottom) - / fabs (geom->y_max - geom->y_min)); + xrchart_write_scale (cr, geom, smin, smax, ticks, SCALE_ORDINATE); +} - for (y = geom->y_min; y <= geom->y_max; y += tick_interval) - draw_tick (cr, geom, TICK_ORDINATE, - (y - geom->y_min) * geom->ordinate_scale, "%g", y); +/* Set the scale for the abscissa */ +void +xrchart_write_xscale (cairo_t *cr, struct xrchart_geometry *geom, + double smin, double smax, int ticks) +{ + xrchart_write_scale (cr, geom, smin, smax, ticks, SCALE_ABSCISSA); } + /* Write the abscissa label */ void xrchart_write_xlabel (cairo_t *cr, const struct xrchart_geometry *geom, const char *label) { - cairo_move_to (cr, geom->data_left, geom->abscissa_top); + cairo_move_to (cr, geom->axis[SCALE_ABSCISSA].data_min, geom->abscissa_top); xrchart_label (cr, 'l', 't', geom->font_size, label); } @@ -346,7 +346,7 @@ xrchart_write_ylabel (cairo_t *cr, const struct xrchart_geometry *geom, const char *label) { cairo_save (cr); - cairo_translate (cr, -geom->data_bottom, -geom->ordinate_right); + cairo_translate (cr, -geom->axis[SCALE_ORDINATE].data_min, -geom->ordinate_right); cairo_move_to (cr, 0, 0); cairo_rotate (cr, M_PI / 2.0); xrchart_label (cr, 'l', 'x', geom->font_size, label); @@ -362,7 +362,7 @@ xrchart_write_legend (cairo_t *cr, const struct xrchart_geometry *geom) const int xpad = 10; const int ypad = 10; const int swatch = 20; - const int legend_top = geom->data_top; + const int legend_top = geom->axis[SCALE_ORDINATE].data_max; const int legend_bottom = legend_top - (vstep * geom->n_datasets + 2 * ypad ); @@ -425,8 +425,8 @@ void xrchart_datum (cairo_t *cr, const struct xrchart_geometry *geom, int dataset UNUSED, double x, double y) { - double x_pos = (x - geom->x_min) * geom->abscissa_scale + geom->data_left; - double y_pos = (y - geom->y_min) * geom->ordinate_scale + geom->data_bottom; + double x_pos = (x - geom->axis[SCALE_ABSCISSA].min) * geom->axis[SCALE_ABSCISSA].scale + geom->axis[SCALE_ABSCISSA].data_min; + double y_pos = (y - geom->axis[SCALE_ORDINATE].min) * geom->axis[SCALE_ORDINATE].scale + geom->axis[SCALE_ORDINATE].data_min; xrchart_draw_marker (cr, x_pos, y_pos, XRMARKER_SQUARE, 15); } @@ -444,10 +444,10 @@ void xrchart_vector (cairo_t *cr, struct xrchart_geometry *geom, double x, double y) { const double x_pos = - (x - geom->x_min) * geom->abscissa_scale + geom->data_left ; + (x - geom->axis[SCALE_ABSCISSA].min) * geom->axis[SCALE_ABSCISSA].scale + geom->axis[SCALE_ABSCISSA].data_min ; const double y_pos = - (y - geom->y_min) * geom->ordinate_scale + geom->data_bottom ; + (y - geom->axis[SCALE_ORDINATE].min) * geom->axis[SCALE_ORDINATE].scale + geom->axis[SCALE_ORDINATE].data_min ; if (geom->in_path) cairo_line_to (cr, x_pos, y_pos); @@ -488,10 +488,10 @@ xrchart_line(cairo_t *cr, const struct xrchart_geometry *geom, y2 = slope * x2 + intercept; } - y1 = (y1 - geom->y_min) * geom->ordinate_scale + geom->data_bottom; - y2 = (y2 - geom->y_min) * geom->ordinate_scale + geom->data_bottom; - x1 = (x1 - geom->x_min) * geom->abscissa_scale + geom->data_left; - x2 = (x2 - geom->x_min) * geom->abscissa_scale + geom->data_left; + y1 = (y1 - geom->axis[SCALE_ORDINATE].min) * geom->axis[SCALE_ORDINATE].scale + geom->axis[SCALE_ORDINATE].data_min; + y2 = (y2 - geom->axis[SCALE_ORDINATE].min) * geom->axis[SCALE_ORDINATE].scale + geom->axis[SCALE_ORDINATE].data_min; + x1 = (x1 - geom->axis[SCALE_ABSCISSA].min) * geom->axis[SCALE_ABSCISSA].scale + geom->axis[SCALE_ABSCISSA].data_min; + x2 = (x2 - geom->axis[SCALE_ABSCISSA].min) * geom->axis[SCALE_ABSCISSA].scale + geom->axis[SCALE_ABSCISSA].data_min; cairo_move_to (cr, x1, y1); cairo_line_to (cr, x2, y2); diff --git a/src/output/cairo-chart.h b/src/output/cairo-chart.h index 1a23dd1793..5e8123ed1a 100644 --- a/src/output/cairo-chart.h +++ b/src/output/cairo-chart.h @@ -31,16 +31,20 @@ struct xrchart_colour uint8_t blue; }; +struct xrchart_axis +{ + int data_max; + int data_min; + + double scale; + double min; + double max; +}; + /* The geometry of a chart. */ struct xrchart_geometry { - int data_top; - int data_right; - int data_bottom; - int data_left; - int abscissa_top; - int ordinate_right; int title_bottom; @@ -57,12 +61,9 @@ struct xrchart_geometry struct xrchart_colour fill_colour; /* Stuff particular to cartesians and boxplots. */ - double ordinate_scale; - double abscissa_scale; - double x_min; - double x_max; - double y_min; - double y_max; + struct xrchart_axis axis[2]; + + /* True iff a path is currently being drawn */ bool in_path; }; @@ -75,8 +76,8 @@ extern const struct xrchart_colour data_colour[]; enum tick_orientation { - TICK_ABSCISSA=0, - TICK_ORDINATE + SCALE_ABSCISSA=0, + SCALE_ORDINATE }; enum xrmarker_type diff --git a/src/output/charts/boxplot-cairo.c b/src/output/charts/boxplot-cairo.c index 1660e86b2d..6aaa600be9 100644 --- a/src/output/charts/boxplot-cairo.c +++ b/src/output/charts/boxplot-cairo.c @@ -31,7 +31,7 @@ static void draw_case (cairo_t *cr, const struct xrchart_geometry *geom, double centreline, const struct outlier *outlier) { - double y = geom->data_bottom + (outlier->value - geom->y_min) * geom->ordinate_scale; + double y = geom->axis[SCALE_ORDINATE].data_min + (outlier->value - geom->axis[SCALE_ORDINATE].min) * geom->axis[SCALE_ORDINATE].scale; xrchart_draw_marker (cr, centreline, y, outlier->extreme ? XRMARKER_ASTERISK : XRMARKER_CIRCLE, 20); @@ -65,14 +65,14 @@ boxplot_draw_box (cairo_t *cr, const struct xrchart_geometry *geom, box_whisker_whiskers (bw, whisker); box_whisker_hinges (bw, hinge); - box_bottom = geom->data_bottom + (hinge[0] - geom->y_min ) * geom->ordinate_scale; + box_bottom = geom->axis[SCALE_ORDINATE].data_min + (hinge[0] - geom->axis[SCALE_ORDINATE].min ) * geom->axis[SCALE_ORDINATE].scale; - box_top = geom->data_bottom + (hinge[2] - geom->y_min ) * geom->ordinate_scale; + box_top = geom->axis[SCALE_ORDINATE].data_min + (hinge[2] - geom->axis[SCALE_ORDINATE].min ) * geom->axis[SCALE_ORDINATE].scale; - bottom_whisker = geom->data_bottom + (whisker[0] - geom->y_min) * - geom->ordinate_scale; + bottom_whisker = geom->axis[SCALE_ORDINATE].data_min + (whisker[0] - geom->axis[SCALE_ORDINATE].min) * + geom->axis[SCALE_ORDINATE].scale; - top_whisker = geom->data_bottom + (whisker[1] - geom->y_min) * geom->ordinate_scale; + top_whisker = geom->axis[SCALE_ORDINATE].data_min + (whisker[1] - geom->axis[SCALE_ORDINATE].min) * geom->axis[SCALE_ORDINATE].scale; /* Draw the box */ cairo_rectangle (cr, @@ -94,10 +94,10 @@ boxplot_draw_box (cairo_t *cr, const struct xrchart_geometry *geom, cairo_set_line_width (cr, cairo_get_line_width (cr) * 5); cairo_move_to (cr, box_left, - geom->data_bottom + (hinge[1] - geom->y_min) * geom->ordinate_scale); + geom->axis[SCALE_ORDINATE].data_min + (hinge[1] - geom->axis[SCALE_ORDINATE].min) * geom->axis[SCALE_ORDINATE].scale); cairo_line_to (cr, box_right, - geom->data_bottom + (hinge[1] - geom->y_min) * geom->ordinate_scale); + geom->axis[SCALE_ORDINATE].data_min + (hinge[1] - geom->axis[SCALE_ORDINATE].min) * geom->axis[SCALE_ORDINATE].scale); cairo_stroke (cr); cairo_restore (cr); @@ -131,7 +131,7 @@ boxplot_draw_box (cairo_t *cr, const struct xrchart_geometry *geom, } /* Draw tick mark on x axis */ - draw_tick(cr, geom, TICK_ABSCISSA, box_centre - geom->data_left, "%s", name); + draw_tick(cr, geom, SCALE_ABSCISSA, box_centre - geom->axis[SCALE_ABSCISSA].data_min, "%s", name); } static void @@ -141,21 +141,21 @@ boxplot_draw_yscale (cairo_t *cr, struct xrchart_geometry *geom, double y_tick; double d; - geom->y_max = y_max; - geom->y_min = y_min; + geom->axis[SCALE_ORDINATE].max = y_max; + geom->axis[SCALE_ORDINATE].min = y_min; - y_tick = chart_rounded_tick (fabs (geom->y_max - geom->y_min) / 5.0); + y_tick = chart_rounded_tick (fabs (geom->axis[SCALE_ORDINATE].max - geom->axis[SCALE_ORDINATE].min) / 5.0); - geom->y_min = (ceil (geom->y_min / y_tick) - 1.0) * y_tick; + geom->axis[SCALE_ORDINATE].min = (ceil (geom->axis[SCALE_ORDINATE].min / y_tick) - 1.0) * y_tick; - geom->y_max = (floor (geom->y_max / y_tick) + 1.0) * y_tick; + geom->axis[SCALE_ORDINATE].max = (floor (geom->axis[SCALE_ORDINATE].max / y_tick) + 1.0) * y_tick; - geom->ordinate_scale = (fabs (geom->data_top - geom->data_bottom) - / fabs (geom->y_max - geom->y_min)); + geom->axis[SCALE_ORDINATE].scale = (fabs (geom->axis[SCALE_ORDINATE].data_max - geom->axis[SCALE_ORDINATE].data_min) + / fabs (geom->axis[SCALE_ORDINATE].max - geom->axis[SCALE_ORDINATE].min)); - for (d = geom->y_min; d <= geom->y_max; d += y_tick) - draw_tick (cr, geom, TICK_ORDINATE, - (d - geom->y_min) * geom->ordinate_scale, "%g", d); + for (d = geom->axis[SCALE_ORDINATE].min; d <= geom->axis[SCALE_ORDINATE].max; d += y_tick) + draw_tick (cr, geom, SCALE_ORDINATE, + (d - geom->axis[SCALE_ORDINATE].min) * geom->axis[SCALE_ORDINATE].scale, "%g", d); } void @@ -169,11 +169,11 @@ xrchart_draw_boxplot (const struct chart_item *chart_item, cairo_t *cr, boxplot_draw_yscale (cr, geom, boxplot->y_max, boxplot->y_min); xrchart_write_title (cr, geom, "%s", chart_item->title); - box_width = (geom->data_right - geom->data_left) / boxplot->n_boxes / 2.0; + box_width = (geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ABSCISSA].data_min) / boxplot->n_boxes / 2.0; for (i = 0; i < boxplot->n_boxes; i++) { const struct boxplot_box *box = &boxplot->boxes[i]; - const double box_centre = (i * 2 + 1) * box_width + geom->data_left; + const double box_centre = (i * 2 + 1) * box_width + geom->axis[SCALE_ABSCISSA].data_min; boxplot_draw_box (cr, geom, box_centre, box_width, box->bw, box->label); } } diff --git a/src/output/charts/piechart-cairo.c b/src/output/charts/piechart-cairo.c index 9e55c56f46..7b847f123e 100644 --- a/src/output/charts/piechart-cairo.c +++ b/src/output/charts/piechart-cairo.c @@ -57,17 +57,17 @@ xrchart_draw_piechart (const struct chart_item *chart_item, cairo_t *cr, double angle; int i; - centre_x = (geom->data_right + geom->data_left) / 2.0 ; - centre_y = (geom->data_top + geom->data_bottom) / 2.0 ; + centre_x = (geom->axis[SCALE_ABSCISSA].data_max + geom->axis[SCALE_ORDINATE].data_min) / 2.0 ; + centre_y = (geom->axis[SCALE_ORDINATE].data_max + geom->axis[SCALE_ORDINATE].data_min) / 2.0 ; - left_label = geom->data_left + (geom->data_right - geom->data_left)/10.0; - right_label = geom->data_right - (geom->data_right - geom->data_left)/10.0; + left_label = geom->axis[SCALE_ORDINATE].data_min + (geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ORDINATE].data_min)/10.0; + right_label = geom->axis[SCALE_ABSCISSA].data_max - (geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ORDINATE].data_min)/10.0; - radius = MIN (5.0 / 12.0 * (geom->data_top - geom->data_bottom), - 1.0 / 4.0 * (geom->data_right - geom->data_left)); + radius = MIN (5.0 / 12.0 * (geom->axis[SCALE_ORDINATE].data_max - geom->axis[SCALE_ORDINATE].data_min), + 1.0 / 4.0 * (geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ORDINATE].data_min)); - radius = MIN (5.0 / 12.0 * (geom->data_top - geom->data_bottom), - 1.0 / 4.0 * (geom->data_right - geom->data_left)); + radius = MIN (5.0 / 12.0 * (geom->axis[SCALE_ORDINATE].data_max - geom->axis[SCALE_ORDINATE].data_min), + 1.0 / 4.0 * (geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ORDINATE].data_min)); xrchart_write_title (cr, geom, "%s", chart_item_get_title (chart_item)); diff --git a/src/output/charts/plot-hist-cairo.c b/src/output/charts/plot-hist-cairo.c index 7c09b6df73..9ce4abb3ed 100644 --- a/src/output/charts/plot-hist-cairo.c +++ b/src/output/charts/plot-hist-cairo.c @@ -33,7 +33,7 @@ static void histogram_write_legend (cairo_t *cr, const struct xrchart_geometry *geom, double n, double mean, double stddev) { - double y = geom->data_bottom; + double y = geom->axis[SCALE_ORDINATE].data_min; cairo_save (cr); if (n != SYSMIS) @@ -74,18 +74,18 @@ hist_draw_bar (cairo_t *cr, const struct xrchart_geometry *geom, double height; const size_t bins = gsl_histogram_bins (h); - const double x_pos = (geom->data_right - geom->data_left) * bar / (double) bins ; - const double width = (geom->data_right - geom->data_left) / (double) bins ; + const double x_pos = (geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ABSCISSA].data_min) * bar / (double) bins ; + const double width = (geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ABSCISSA].data_min) / (double) bins ; assert ( 0 == gsl_histogram_get_range (h, bar, &lower, &upper)); assert ( upper >= lower); height = gsl_histogram_get (h, bar) / - (geom->y_max - geom->y_min) * - (geom->data_top - geom->data_bottom); + (geom->axis[SCALE_ORDINATE].max - geom->axis[SCALE_ORDINATE].min) * + (geom->axis[SCALE_ORDINATE].data_max - geom->axis[SCALE_ORDINATE].data_min); - cairo_rectangle (cr, geom->data_left + x_pos, geom->data_bottom, + cairo_rectangle (cr, geom->axis[SCALE_ABSCISSA].data_min + x_pos, geom->axis[SCALE_ORDINATE].data_min, width, height); cairo_save (cr); cairo_set_source_rgb (cr, @@ -96,7 +96,7 @@ hist_draw_bar (cairo_t *cr, const struct xrchart_geometry *geom, cairo_restore (cr); cairo_stroke (cr); - draw_tick (cr, geom, TICK_ABSCISSA, + draw_tick (cr, geom, SCALE_ABSCISSA, x_pos + width / 2.0, "%g", (upper + lower) / 2.0); } @@ -142,20 +142,20 @@ xrchart_draw_histogram (const struct chart_item *chart_item, cairo_t *cr, range = not_used - x_min; gsl_histogram_get_range (h->gsl_hist, bins - 1, ¬_used, &x_max); - abscissa_scale = (geom->data_right - geom->data_left) / (x_max - x_min); - ordinate_scale = (geom->data_top - geom->data_bottom) / + abscissa_scale = (geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ABSCISSA].data_min) / (x_max - x_min); + ordinate_scale = (geom->axis[SCALE_ORDINATE].data_max - geom->axis[SCALE_ORDINATE].data_min) / gsl_histogram_max_val (h->gsl_hist); - cairo_move_to (cr, geom->data_left, geom->data_bottom); - for (d = geom->data_left; - d <= geom->data_right; - d += (geom->data_right - geom->data_left) / 100.0) + cairo_move_to (cr, geom->axis[SCALE_ABSCISSA].data_min, geom->axis[SCALE_ORDINATE].data_min); + for (d = geom->axis[SCALE_ABSCISSA].data_min; + d <= geom->axis[SCALE_ABSCISSA].data_max; + d += (geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ABSCISSA].data_min) / 100.0) { - const double x = (d - geom->data_left) / abscissa_scale + x_min; + const double x = (d - geom->axis[SCALE_ABSCISSA].data_min) / abscissa_scale + x_min; const double y = h->n * range * gsl_ran_gaussian_pdf (x - h->mean, h->stddev); - cairo_line_to (cr, d, geom->data_bottom + y * ordinate_scale); + cairo_line_to (cr, d, geom->axis[SCALE_ORDINATE].data_min + y * ordinate_scale); } cairo_stroke (cr);