void shoes_plot_draw_scatter_pts(cairo_t *cr, shoes_plot *plot) { // first series (x) controls graphical settings. if (plot->seriescnt != 2) return; // we don't have just two series int i; int top,left,bottom,right; left = plot->graph_x; top = plot->graph_y; right = plot->graph_w; bottom = plot->graph_h; int height = bottom - top; int width = right - left; VALUE rbxser, rbyser; shoes_chart_series *serx, *sery; rbxser = rb_ary_entry(plot->series, 0); Data_Get_Struct(rbxser, shoes_chart_series, serx); rbyser = rb_ary_entry(plot->series, 1); Data_Get_Struct(rbyser, shoes_chart_series, sery); double xmax = NUM2DBL(serx->maxv); double ymax = NUM2DBL(sery->maxv); double xmin = NUM2DBL(serx->minv); double ymin = NUM2DBL(sery->minv); int nubs = NUM2INT(serx->point_type); VALUE shcolor = serx->color; VALUE rbstroke = serx->strokes; int strokew = NUM2INT(rbstroke); if (strokew < 1) strokew = 1; shoes_color *color; Data_Get_Struct(shcolor, shoes_color, color); int obvs = RARRAY_LEN(serx->values); for (i = 0; i < obvs; i++) { double xval, yval; xval = NUM2DBL(rb_ary_entry(serx->values, i)); yval = NUM2DBL(rb_ary_entry(sery->values, i)); //printf("scatter x: %f, y: %f\n", xval, yval); } double yScale = height / (ymax - ymin); double xScale = width / (xmax - xmin); cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0, color->b / 255.0, color->a / 255.0); for (i = 0; i < obvs; i++) { VALUE rbx = rb_ary_entry(serx->values, i); double xval = NUM2DBL(rbx); VALUE rby = rb_ary_entry(sery->values, i); double yval = NUM2DBL(rby); long x = roundl((xval - xmin) * xScale); long y = height - roundl((yval - ymin) * yScale); x += left; y += top; //printf("x: %f, y: %f --> x: %i px, y: %i, px\n", xval, yval, x, y); // lets draw a nub at x, y cairo_move_to(cr, x, y); shoes_plot_draw_nub(cr, plot, x, y, nubs, strokew + 2); } cairo_stroke(cr); shoes_plot_set_cairo_default(cr, plot); }
void shoes_plot_draw_boundbox(cairo_t *cr, shoes_plot *plot) { // draw box around data area (plot->graph_?) shoes_plot_set_cairo_default(cr, plot); int t,l,b,r; l = plot->graph_x; t = plot->graph_y; r = plot->graph_w; b = plot->graph_h; cairo_move_to(cr, l, t); cairo_line_to(cr, r, t); // across top cairo_line_to(cr, r, b); // down right side cairo_line_to(cr, l, b); // across bottom cairo_line_to(cr, l, t); // up left cairo_stroke(cr); }
// fill graph area with background color void shoes_plot_draw_fill(cairo_t *cr, shoes_plot *plot) { if (NIL_P(plot->background)) { cairo_set_source_rgba(cr, 0.99, 0.99, 0.99, 0.99); } else { shoes_color *color; Data_Get_Struct(plot->background, shoes_color, color); cairo_set_source_rgba(cr, color->r / 255.0 , color->g / 255.0 , color->b / 255.0 , color->a / 255.0 ); } cairo_set_line_width(cr, 1); cairo_rectangle(cr, 0, 0, plot->place.w, plot->place.h); cairo_fill(cr); shoes_plot_set_cairo_default(cr, plot); }
// called at draw time. Calls many other functions. // Whole lotta drawing going on // Note: we expand the margins a bit shoe we can draw the label vertically void shoes_plot_scatter_draw(cairo_t *cr, shoes_place *place, shoes_plot *self_t) { shoes_plot_set_cairo_default(cr, self_t); shoes_plot_draw_fill(cr, self_t); shoes_plot_draw_title(cr, self_t); shoes_plot_draw_caption(cr, self_t); if (self_t->boundbox) shoes_plot_draw_boundbox(cr, self_t); self_t->graph_h = self_t->place.h - (self_t->title_h + self_t->caption_h); self_t->graph_y = self_t->title_h + 3; self_t->yaxis_offset = 70; // TODO: run TOTO! run! self_t->graph_w = self_t->place.w - self_t->yaxis_offset; self_t->graph_x = self_t->yaxis_offset; if (self_t->seriescnt) { // draw box, ticks and x,y labels. shoes_plot_scatter_ticks_and_labels(cr, self_t); shoes_plot_scatter_legend(cr, self_t); shoes_plot_draw_scatter_pts(cr, self_t); } }
void shoes_plot_draw_columns(cairo_t *cr, shoes_plot *plot) { int i, num_series; int top,left,bottom,right; left = plot->graph_x; top = plot->graph_y; right = plot->graph_w; bottom = plot->graph_h; int width = right - left; int height = bottom - top; // need to compute x advance based on number of series and stroke width int colsw = 0; // combined stroke width for one set of bars num_series = plot->seriescnt; int strokesw[num_series]; double maximums[num_series]; double minimums[num_series]; double vScales[num_series]; shoes_color *colors[num_series]; int nubs[num_series]; VALUE values[num_series]; VALUE labels[num_series]; int range = plot->end_idx - plot->beg_idx; // zooming adj // load local var arrays for (i = 0; i < plot->seriescnt; i++) { VALUE rbser = rb_ary_entry(plot->series, i); shoes_chart_series *cs; Data_Get_Struct(rbser, shoes_chart_series, cs); values[i] = cs->values; labels[i] = cs->labels; maximums[i] = NUM2DBL(cs->maxv); minimums[i] = NUM2DBL(cs->minv); nubs[i] = (width / range > 10) ? RTEST(cs->point_type) : 0; Data_Get_Struct(cs->color, shoes_color, colors[i]); int sw = NUM2INT(cs->strokes); if (sw < 4) sw = 4; strokesw[i] = sw; colsw += sw; vScales[i] = (height / (maximums[i] - minimums[i])); //values[i] = rb_ary_entry(plot->values, i); //VALUE rbmaxv = rb_ary_entry(plot->maxvs, i); //VALUE rbminv = rb_ary_entry(plot->minvs, i); //maximums[i] = NUM2DBL(rbmaxv); //minimums[i] = NUM2DBL(rbminv); //VALUE rbnubs = rb_ary_entry(plot->nubs, i); //nubs[i] = (width / range > 10) ? RTEST(rbnubs) : 0; //VALUE rbcolor = rb_ary_entry(plot->color, i); //VALUE rbstroke = rb_ary_entry(plot->strokes, i); //int sw = NUM2INT(rbstroke); //if (sw < 4) sw = 4; //strokesw[i] = sw; //colsw += sw; //vScales[i] = (height / (maximums[i] - minimums[i])); //Data_Get_Struct(rbcolor, shoes_color, colors[i]); } int ncolsw = width / (range) ; // int xinset = left + (ncolsw / 2); // start inside the box, half a width int xpos = xinset; //printf("ncolsw: w: %i, advw: %i, start inset %i\n", width, ncolsw, xpos); for (i = plot->beg_idx; i < plot->end_idx; i++) { int j; for (j = 0; j < plot->seriescnt; j++) { VALUE rbdp = rb_ary_entry(values[j], i + plot->beg_idx); if (NIL_P(rbdp)) { printf("skipping nil at %i\n", i + plot->beg_idx); continue; } double v = NUM2DBL(rbdp); cairo_set_line_width(cr, strokesw[j]); cairo_set_source_rgba(cr, colors[j]->r / 255.0, colors[j]->g / 255.0, colors[j]->b / 255.0, colors[j]->a / 255.0); long y = height - roundl((v - minimums[j]) * vScales[j]); //printf("move i: %i, j: %i, x: %i, v: %f -> y: %i,%i \n", i, j, xpos, v, y, y+top); y += top; cairo_move_to(cr, xpos, bottom); cairo_line_to(cr, xpos, y); cairo_stroke(cr); xpos += strokesw[j]; } // draw xaxis labels. shoes_plot_set_cairo_default(cr, plot); // reset to default VALUE obs = rb_ary_entry(labels[0], i + plot->beg_idx); //VALUE obs = rb_ary_entry(rbobs, i + plot->beg_idx); shoes_plot_column_xaxis(cr, plot, xpos-(colsw / 2), obs); xpos = (ncolsw * (i + 1)) + xinset; } // tell cairo to draw all lines (and points) not already drawn. cairo_stroke(cr); // set color back to dark gray and stroke to 1 //cairo_set_source_rgba(cr, 0.9, 0.9, 0.9, 1.0); //cairo_set_line_width(cr, 1.0); shoes_plot_set_cairo_default(cr, plot); }