Skip to content

Commit

Permalink
for #264 - create chart_series internally
Browse files Browse the repository at this point in the history
* when a hash is given to plot.add - moves arg parse to chart_series_new
* update each Test to use both a hash and an explicit chart_series
  • Loading branch information
Cecil committed Oct 18, 2016
1 parent b71131b commit 5e20419
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 157 deletions.
9 changes: 6 additions & 3 deletions Tests/plot/gr1.rb
Expand Up @@ -25,9 +25,12 @@
points: true
flow do
button "add #2" do
@grf.add values: @values2,
name: "bartab", min: @values2.min, max: @values2.max , color: "coral",
strokewidth: 3 #, points: true
cs2 = app.chart_series values: @values2, name: "bartab", min: @values2.min, max: @values2.max , color: "coral",
strokewidth: 3
@grf.add cs2
#@grf.add values: @values2,
# name: "bartab", min: @values2.min, max: @values2.max , color: "coral",
# strokewidth: 3 #, points: true
end
button "delete #2" do
@grf.delete(1)
Expand Down
6 changes: 5 additions & 1 deletion Tests/plot/gr2.rb
Expand Up @@ -25,9 +25,13 @@

end
end
@grf.add values: @values1, labels: @x_axis1,
cs1 = app.chart_series values: @values1, labels: @x_axis1,
name: "foobar", min: 6, max: 26 , desc: "foobar Yy", color: "dodgerblue",
points: true
@grf.add cs1
#@grf.add values: @values1, labels: @x_axis1,
# name: "foobar", min: 6, max: 26 , desc: "foobar Yy", color: "dodgerblue",
# points: true
@grf2.add values: @values2, labels: @x_axis2,
name: "Bar", min: 50, max: 250, desc: "BarBaz", color: "dodgerblue",
points: true
Expand Down
6 changes: 5 additions & 1 deletion Tests/plot/gr3.rb
Expand Up @@ -35,9 +35,13 @@
@grf2.add values: @values1, labels: @x_axis1,
name: "Bar", min: 0, max: 30, desc: "foobar Yy", color: "crimson",
points: true, strokewidth: 12
@grf2.add values: @values2, labels: @x_axis2,
cs2 = app.chart_series values: @values2, labels: @x_axis2,
name: "Tab", min: 50, max: 230, desc: "BarTab", color: "green",
points: true, strokewidth: 6
@grf2.add cs2
#@grf2.add values: @values2, labels: @x_axis2,
# name: "Tab", min: 50, max: 230, desc: "BarTab", color: "green",
# points: true, strokewidth: 6
end
end

13 changes: 7 additions & 6 deletions Tests/plot/gr4.rb
Expand Up @@ -21,12 +21,13 @@
@grf.add values: @values1,
name: "Wind", min: 12.5, max: 35 , color: "dodgerblue",
points: "dot", strokewidth: 1
#cs = app.chart_series values: @values2, name: "Clouds",
# min: 10, max: 50 , color: "black",
# points: "box", strokewidth: 1, desc: "Cloud Cover (percentage)"
@grf.add values: @values2, name: "Clouds",
desc: "Cloud Cover (percentage)", min: 10, max: 50 , color: "black",
points: "box", strokewidth: 1
cs = app.chart_series values: @values2, name: "Clouds",
min: 10, max: 50 , color: "black",
points: "box", strokewidth: 1, desc: "Cloud Cover (percentage)"
@grf.add cs
#@grf.add values: @values2, name: "Clouds",
# desc: "Cloud Cover (percentage)", min: 10, max: 50 , color: "black",
# points: "box", strokewidth: 1
end
end

7 changes: 5 additions & 2 deletions Tests/plot/gr5.rb
Expand Up @@ -19,8 +19,11 @@
default: "skip", background: "white", chart: "pie", pie_percent: false
end
end
@grf.add values: @values1, labels: @obs1,
name: "download", min: @values1.min, max: @values1.max #, color: "dodgerblue",
cs = app.chart_series values: @values1, labels: @obs1,
name: "download", min: @values1.min, max: @values1.max
@grf.add cs
#@grf.add values: @values1, labels: @obs1,
#name: "download", min: @values1.min, max: @values1.max #, color: "dodgerblue",
#points: "dot", strokewidth: 1
end
end
Expand Down
1 change: 0 additions & 1 deletion shoes/plot/chart_series.c
Expand Up @@ -72,7 +72,6 @@ shoes_chart_series_new(int argc, VALUE *argv, VALUE self)
VALUE rbsz, rbvals, rblabels, rbmin, rbmax, rbname, rbdesc, rbcolor;
VALUE rbstroke, rbpoint, rbpoint_type = Qnil;
VALUE color_wrapped = Qnil;
Data_Get_Struct(self, shoes_chart_series, self_t);
rb_arg_list args;
switch (rb_parse_args(argc, argv, "h", &args)) {
case 1:
Expand Down
155 changes: 12 additions & 143 deletions shoes/plot/plot.c
Expand Up @@ -306,24 +306,29 @@ void shoes_plot_draw_everything(cairo_t *cr, shoes_place *place, shoes_plot *sel
self_t->place = *place;
}

VALUE shoes_plot_add(VALUE self, VALUE newseries)
VALUE shoes_plot_add(VALUE self, VALUE theseries)
{
shoes_plot *self_t;
VALUE rbsz, rbvals, rbobs, rbmin, rbmax, rbshname, rblgname, rbcolor;
VALUE rbstroke, rbnubs, rbnubtype = Qnil;
VALUE color_wrapped = Qnil;
Data_Get_Struct(self, shoes_plot, self_t);
int i = self_t->seriescnt; // track number of series to plot.
VALUE newseries = theseries;
if (i >= 6) {
rb_raise(rb_eArgError, "Maximum of 6 series");
}
// chartseries has already parsed it's args.
// we got hash - convert it to a chart_series
if (TYPE(theseries) == T_HASH) {
newseries = shoes_chart_series_new(1, &theseries, self);
}

if (rb_obj_is_kind_of(newseries, cChartSeries)) {
shoes_chart_series *cs;
Data_Get_Struct(newseries, shoes_chart_series, cs);
rbsz = RARRAY_LEN(cs->values);
int nobs = RARRAY_LEN(cs->values);
self_t->beg_idx = 0;
self_t->end_idx = NUM2INT(rbsz);
self_t->end_idx = nobs;
self_t->seriescnt++;
rb_ary_store(self_t->series, i, newseries);
// radar & pie chart types need to pre-compute some geometery and store it
Expand All @@ -336,145 +341,9 @@ VALUE shoes_plot_add(VALUE self, VALUE newseries)
shoes_canvas_repaint_all(self_t->parent);
return self;
}

if (TYPE(newseries) == T_HASH) {

rbvals = shoes_hash_get(newseries, rb_intern("values"));
rbobs = shoes_hash_get(newseries, rb_intern("labels"));
rbmin = shoes_hash_get(newseries, rb_intern("min"));
rbmax = shoes_hash_get(newseries, rb_intern("max"));
rbshname = shoes_hash_get(newseries, rb_intern("name"));
rblgname = shoes_hash_get(newseries, rb_intern("desc"));
rbcolor = shoes_hash_get(newseries, rb_intern("color"));
rbstroke = shoes_hash_get(newseries, rb_intern("strokewidth"));
rbnubs = shoes_hash_get(newseries, rb_intern("points"));

if ( NIL_P(rbvals) || TYPE(rbvals) != T_ARRAY ) {
rb_raise(rb_eArgError, "plot.add: Missing an Array of values");
}
int valsz = RARRAY_LEN(rbvals);
// printf("values rarray_len: %d\n", valsz);
rbsz = INT2NUM(valsz);
if (NIL_P(rbmin) || NIL_P(rbmax)) {
rb_raise(rb_eArgError, "plot.add: Missing minv: or maxv: option");
}
int need_x_strings = (self_t->chart_type == LINE_CHART ||
self_t->chart_type == COLUMN_CHART ||
self_t->chart_type == TIMESERIES_CHART);
if ( NIL_P(rbobs) && need_x_strings) {
// we can fake it - poorly - TODO: call a user given proc ?
int l = NUM2INT(rbsz);
int i;
rbobs = rb_ary_new2(l);
for (i = 0; i < l; i++) {
char t[8];
sprintf(t, "%i", i+1);
VALUE foostr = rb_str_new2(t);
rb_ary_store(rbobs, i, foostr);
}
}
if (need_x_strings && TYPE(rbobs) != T_ARRAY ) {
rb_raise(rb_eArgError, "plot.add xobs is not an array");
}
if (NIL_P(rbshname))
rb_raise(rb_eArgError, "plot.add missing name:");

if (NIL_P(rblgname)) {
rblgname = rbshname;
}

// handle colors
if (! NIL_P(rbcolor)) {
if (TYPE(rbcolor) != T_STRING)
rb_raise(rb_eArgError, "plot.add color must be a string");
char *cstr = RSTRING_PTR(rbcolor);
color_wrapped = shoes_hash_get(cColors, rb_intern(cstr));
if (NIL_P(color_wrapped))
rb_raise(rb_eArgError, "plot.add color: not a known color");
} else {
switch (i) {
case 0:
color_wrapped = shoes_hash_get(cColors, rb_intern("blue"));
break;
case 1:
color_wrapped = shoes_hash_get(cColors, rb_intern("red"));
break;
case 2:
color_wrapped = shoes_hash_get(cColors, rb_intern("green"));
break;
case 3:
color_wrapped = shoes_hash_get(cColors, rb_intern("coral"));
break;
case 4:
color_wrapped = shoes_hash_get(cColors, rb_intern("purple"));
break;
case 5:
color_wrapped = shoes_hash_get(cColors, rb_intern("orange"));
break;
}
}

if (!NIL_P(rbstroke)) {
if (TYPE(rbstroke) != T_FIXNUM)
rb_raise(rb_eArgError, "plot.add strokewidth not an integer\n");
} else {
rbstroke = INT2NUM(1); // default
}

// This is weird. We handle :true, :false/nil and string.
if (NIL_P(rbnubs)) {
rbnubtype = INT2NUM(NUB_NONE);
} else if (TYPE(rbnubs) == T_STRING) {
char *req = RSTRING_PTR(rbnubs);
if (!strcmp(req, "dot"))
rbnubtype = INT2NUM(NUB_DOT);
else if (!strcmp(req, "circle"))
rbnubtype = INT2NUM(NUB_CIRCLE);
else if (!strcmp(req, "box"))
rbnubtype = INT2NUM(NUB_BOX);
else if (!strcmp(req, "rect"))
rbnubtype = INT2NUM(NUB_RECT);
else
rb_raise(rb_eArgError, "plot.add nubs: string does not match know nub types\n");
} else if (TYPE(rbnubs) == T_TRUE) {
rbnubtype = INT2NUM(NUB_DOT);
} else if (TYPE(rbnubs) == T_FALSE) {
rbnubtype = INT2NUM(NUB_NONE);
}
} else {
rb_raise(rb_eArgError, "misssing something in plot.add \n");
}
// transition code
VALUE cs;
shoes_chart_series *ser;
switch (self_t->chart_type) {
// charts using the new chart_series class
case PIE_CHART:
case RADAR_CHART:
case SCATTER_CHART:
case COLUMN_CHART:
case LINE_CHART:
case TIMESERIES_CHART:
cs = shoes_chart_series_alloc(cChartSeries);
Data_Get_Struct(cs, shoes_chart_series, ser);
shoes_chart_series_Cinit(ser, rbvals, rbobs, rbmax, rbmin, rbshname, rblgname,
rbstroke, rbnubtype, color_wrapped);
break;
default: // these charts use the old code
;
}
rb_ary_store(self_t->series, i, cs);
self_t->beg_idx = 0;
self_t->end_idx = NUM2INT(rbsz);
self_t->seriescnt++;
// radar & pie chart types need to pre-compute some geometery and store it
// in their own structs.
if (self_t->chart_type == PIE_CHART)
shoes_plot_pie_init(self_t);
else if (self_t->chart_type == RADAR_CHART)
shoes_plot_radar_init(self_t);

shoes_canvas_repaint_all(self_t->parent);
// if we get here, we don't have a chart_series and we couldn't create one
// odds are exceptions have been raised already, but just in case:
rb_raise(rb_eArgError, "plot.add: not a valid hash or chart_series");
return self;
}

Expand Down

0 comments on commit 5e20419

Please sign in to comment.