X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmath%2Fchart-geometry.c;h=26268fd2f32c89032ebb4b5673cc21032b7dfbf5;hb=f89d8a893f83ad0cb95819ca60e6f4a718f7d988;hp=35380a6929b6c4529e0fe2d5579e03cad9b25f23;hpb=6a0bfe2697f4de29cc11782ac6bd2c4175554a9c;p=pspp diff --git a/src/math/chart-geometry.c b/src/math/chart-geometry.c index 35380a6929..26268fd2f3 100644 --- a/src/math/chart-geometry.c +++ b/src/math/chart-geometry.c @@ -23,6 +23,10 @@ #include "decimal.h" #include +#include "gl/xalloc.h" +#include "gl/minmax.h" +#include "gl/xvasprintf.h" + static const double standard_tick[] = {1, 2, 5, 10}; /* Adjust tick to be a sensible value @@ -149,3 +153,72 @@ chart_get_scale (double highdbl, double lowdbl, } } } + +/* + * Compute the optimum format string and the scaling + * for the tick drawing on a chart axis + * Input: max: the maximum value of the range + * min: the minimum value of the range + * nticks: the number of tick intervals (bins) on the axis + * Return: fs: format string for printf to print the tick value + * scale: scaling factor for the tick value + * The format string has to be freed after usage. + * An example format string and scalefactor: + * Non Scientific: "%.3lf", scale=1.00 + * Scientific: "%.2lfe3", scale = 0.001 + * Usage example: + * fs = chart_get_ticks_format(95359943.3,34434.9,8,&scale,&long); + * printf(fs,value*scale); + * free(fs); + */ +char * +chart_get_ticks_format (const double max, const double min, + const unsigned int nticks, double *scale) +{ + assert(max > min); + double interval = (max - min)/nticks; + double logmax = log10(fmax(fabs(max),fabs(min))); + double logintv = log10(interval); + int logshift = 0; + char *format_string = NULL; + int nrdecs = 0; + + if (logmax > 0.0 && logintv < 0.0) + { + nrdecs = MIN(6,(int)(fabs(logintv))+1); + logshift = 0; + format_string = xasprintf("%%.%dlf",nrdecs); + } + else if (logmax > 0.0) /*logintv is > 0*/ + { + if (logintv < 3.0) + { + logshift = 0; /* No scientific format */ + nrdecs = 0; + format_string = xstrdup("%.0lf"); + } + else + { + logshift = (int)logmax; + nrdecs = MIN(6,(int)(logmax-logintv)+1); + format_string = xasprintf("%%.%dlfe%d",nrdecs,logshift); + } + } + else /* logmax and logintv are < 0 */ + { + if (logmax > -3.0) + { + logshift = 0; /* No scientific format */ + nrdecs = (int)(-logintv) + 1; + format_string = xasprintf("%%.%dlf",nrdecs); + } + else + { + logshift = (int)logmax-1; + nrdecs = MIN(6,(int)(logmax-logintv)+1); + format_string = xasprintf("%%.%dlfe%d",nrdecs,logshift); + } + } + *scale = pow(10.0,-(double)logshift); + return format_string; +}