X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fchart.c;h=07111ad925b8c864301a42768f54c5b5209d9870;hb=5156fa5a8323a16f6b4bbc8950221cdc1d0e023d;hp=abf4e70b7d2c4b76af55056453c21e3131eeb932;hpb=02ef5fef5288b80a4822e1006f6cb2b1369a55bd;p=pspp-builds.git diff --git a/src/chart.c b/src/chart.c index abf4e70b..07111ad9 100644 --- a/src/chart.c +++ b/src/chart.c @@ -17,16 +17,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +#include #include #include #include #include +#include #include #include #include #include "chart.h" +#include "str.h" const char *data_colour[] = { @@ -141,14 +143,22 @@ draw_tick(struct chart *chart, +/* Write the title on a chart*/ void -chart_write_title(struct chart *chart, const char *title) +chart_write_title(struct chart *chart, const char *title, ...) { - /* Write the title */ + va_list ap; + char buf[100]; + pl_savestate_r(chart->lp); pl_ffontsize_r(chart->lp,chart->font_size * 1.5); pl_move_r(chart->lp,chart->data_left, chart->title_bottom); - pl_alabel_r(chart->lp,0,0,title); + + va_start(ap,title); + vsnprintf(buf,100,title,ap); + pl_alabel_r(chart->lp,0,0,buf); + va_end(ap); + pl_restorestate_r(chart->lp); } @@ -171,3 +181,83 @@ chart_finalise(struct chart *chart) } + + +/* Adjust tick to be a sensible value + ie: ... 0.1,0.2,0.5, 1,2,5, 10,20,50 ... */ +double +chart_rounded_tick(double tick) +{ + + int i; + + double diff = DBL_MAX; + double t = tick; + + static const double standard_ticks[] = {1, 2, 5, 10}; + + const double factor = pow(10,ceil(log10(standard_ticks[0] / tick))) ; + + for (i = 3 ; i >= 0 ; --i) + { + const double d = fabs( tick - standard_ticks[i] / factor ) ; + + if ( d < diff ) + { + diff = d; + t = standard_ticks[i] / factor ; + } + } + + return t; + +} + + +/* Set the scale for the abscissa */ +void +chart_write_xscale(struct chart *ch, double min, double max, int ticks) +{ + double x; + + const double tick_interval = + chart_rounded_tick( (max - min) / (double) ticks); + + ch->x_max = ceil( max / tick_interval ) * tick_interval ; + ch->x_min = floor ( min / tick_interval ) * tick_interval ; + + ch->abscissa_scale = fabs(ch->data_right - ch->data_left) / + fabs(ch->x_max - ch->x_min); + + for(x = ch->x_min ; x <= ch->x_max; x += tick_interval ) + { + draw_tick (ch, TICK_ABSCISSA, + (x - ch->x_min) * ch->abscissa_scale, "%g", x); + } + +} + + +/* Set the scale for the ordinate */ +void +chart_write_yscale(struct chart *ch, double smin, double smax, int ticks) +{ + double y; + + const double tick_interval = + chart_rounded_tick( (smax - smin) / (double) ticks); + + ch->y_max = ceil ( smax / tick_interval ) * tick_interval ; + ch->y_min = floor ( smin / tick_interval ) * tick_interval ; + + ch->ordinate_scale = + fabs(ch->data_top - ch->data_bottom) / fabs(ch->y_max - ch->y_min) ; + + for(y = ch->y_min ; y <= ch->y_max; y += tick_interval ) + { + draw_tick (ch, TICK_ORDINATE, + (y - ch->y_min) * ch->ordinate_scale, "%g", y); + } + +} +