void shoes_plot_column_xaxis(cairo_t *cr, shoes_plot *plot, int x, VALUE obs) { char *rawstr = RSTRING_PTR(obs); int y; y = plot->graph_h; shoes_plot_draw_label(cr, plot, x, y, rawstr, BELOW); // we don't need to call shoes_plot_set_cairo_default on return // since we know it won't be changed on us. }
void shoes_plot_draw_ticks_and_labels(cairo_t *cr, shoes_plot *plot) { int top, left, bottom, right; // these are cairo abs for plot->graph int width, height; // full plot space so it includes everything int range; int h_padding = 65; // default width of horizontal tick cell TODO: an option in plot-> int v_padding = 25; // default height of tick TODO: an option in plot-> left = plot->graph_x; top = plot->graph_y; right = plot->graph_w; bottom = plot->graph_h; range = plot->end_idx - plot->beg_idx; width = right - left; height = bottom - top; h_padding = width / plot->x_ticks; v_padding = height / plot->y_ticks; double h_scale; int h_interval; h_scale = width / (double) (range -1); h_interval = (int) ceil(h_padding / h_scale); // draw x axis - labels and tick mark uses series[0]->labels[*] - assumes it's strings // in the array -- TODO: allow a proc to be called to create the string. at 'i' int i; VALUE rbxser; shoes_chart_series *serx; rbxser = rb_ary_entry(plot->series, 0); Data_Get_Struct(rbxser, shoes_chart_series, serx); VALUE xobs = serx->labels; if (NIL_P(xobs) || TYPE(xobs) != T_ARRAY) rb_raise (rb_eArgError, "xobs must be an array"); for (i = 0 ; i < range; i++ ) { int x = (int) roundl(i * h_scale); x += left; long y = bottom; if ((i % h_interval) == 0) { char *rawstr; VALUE rbstr = rb_ary_entry(xobs, i + plot->beg_idx); if (NIL_P(rbstr)) { rawstr = " "; } else { rawstr = RSTRING_PTR(rbstr); } //printf("x label i: %i, x: %i, y: %i, \"%s\" %i %f \n", i, (int) x, (int) y, rawstr, h_interval, h_scale); shoes_plot_draw_tick(cr, plot, x, y, VERTICALLY); if (plot->chart_type == LINE_CHART || plot->chart_type == TIMESERIES_CHART) shoes_plot_draw_label(cr, plot, x, y, rawstr, BELOW); } } int j; for (j = 0; j < min(2, plot->seriescnt); j++) { VALUE rbser = rb_ary_entry(plot->series, j); shoes_chart_series *cs; Data_Get_Struct(rbser, shoes_chart_series, cs); double maximum = NUM2DBL(cs->maxv); double minimum = NUM2DBL(cs->minv); double v_scale = height / (maximum - minimum); int v_interval = (int) ceil(v_padding / v_scale); char tstr[16]; long i; for (i = ((long) minimum) + 1 ; i < ((long) roundl(maximum)); i = i + roundl(v_interval)) { int y = (int) (bottom - roundl((i - minimum) * v_scale)); int x = 0; sprintf(tstr, "%i", (int)i); // TODO user specificed format? if (j == 0) { // left side y presentation x = left; //printf("hoz left %i, %i, %s\n", (int)x, (int)y,tstr); shoes_plot_draw_tick(cr, plot, x, y, HORIZONTALLY); shoes_plot_draw_label(cr, plot, x, y, tstr, LEFT); } else { // right side y presentation x = right; shoes_plot_draw_tick(cr, plot, x, y, HORIZONTALLY); shoes_plot_draw_label(cr, plot, x, y, tstr, RIGHT); } } } }
static void shoes_plot_scatter_ticks_and_labels(cairo_t *cr, shoes_plot *plot) { int top, left, bottom, right; // these are cairo abs for plot->graph int width, height; // full plot space so it includes everything int range; int h_padding = 65; int v_padding = 25; left = plot->graph_x; top = plot->graph_y; right = plot->graph_w; bottom = plot->graph_h; range = plot->end_idx - plot->beg_idx; width = right - left; height = bottom - top; h_padding = width / plot->x_ticks; // TODO: rethink. v_padding = height / plot->y_ticks; VALUE rbserx, rbsery; shoes_chart_series *serx, *sery; rbserx = rb_ary_entry(plot->series, 0); rbsery = rb_ary_entry(plot->series, 1); Data_Get_Struct(rbserx, shoes_chart_series, serx); Data_Get_Struct(rbsery, shoes_chart_series, sery); double xmax = NUM2DBL(serx->maxv); double ymax = NUM2DBL(sery->maxv); double xmin = NUM2DBL(serx->minv); double ymin = NUM2DBL(sery->minv); /* VALUE rbxmax = rb_ary_entry(plot->maxvs, 0); VALUE rbymax = rb_ary_entry(plot->maxvs, 1); VALUE rbxmin = rb_ary_entry(plot->minvs, 0); VALUE rbymin = rb_ary_entry(plot->minvs, 1); double xmax = NUM2DBL(rbxmax); double ymax = NUM2DBL(rbymax); double xmin = NUM2DBL(rbxmin); double ymin = NUM2DBL(rbymin); */ double h_scale; int h_interval; //h_scale = width / (double) (range -1); h_scale = width / (double) (range ); h_interval = (int) ceil(h_padding / h_scale); char tstr[10]; // draw x axis - labels and tick marks generated between xmin-->xmax int i; for (i = 0 ; i < range; i++ ) { int x = (int) roundl(i * h_scale); x += left; long y = bottom; if ((i % h_interval) == 0) { char rawstr[10]; // convert i to number in the range of xmin->xmax sprintf(rawstr, "%4.2f", xmin + ((xmax - xmin) / range) * i); // Do not trust!! shoes_plot_draw_tick(cr, plot, x, y, VERTICALLY); shoes_plot_draw_label(cr, plot, x, y, rawstr, BELOW); } } // draw the last label on x sprintf(tstr, "%4.2f", xmax); shoes_plot_draw_label(cr, plot, right, bottom, tstr, BELOW); // draw y axis - there is only one in a Shoes scatter plot double v_scale = height / (ymax - ymin); double j; int v_interval = (int) ceil(v_padding / v_scale); //printf("v_scale: %f, v_interval: %i\n", v_scale, v_interval); for (j = ymin ; j < ymax; j += v_interval) { int y = (int) (bottom - roundl((j - ymin) * v_scale)); int x = left; sprintf(tstr, "%4.2f", j); //printf("hoz left %i, %i, %s\n", (int)x, (int)y, tstr); shoes_plot_draw_tick(cr, plot, x, y, HORIZONTALLY); shoes_plot_draw_label(cr, plot, x, y, tstr, LEFT); } // print top label sprintf(tstr, "%4.2f", ymax); shoes_plot_draw_label(cr, plot, left, top, tstr, LEFT); }