Fixed bug #11227 (T-Test not working with alpha independent variable )
[pspp-builds.git] / src / chart.c
index abf4e70b7d2c4b76af55056453c21e3131eeb932..07111ad925b8c864301a42768f54c5b5209d9870 100644 (file)
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA. */
 
-
+#include <config.h>
 #include <stdio.h>
 #include <plot.h>
 #include <stdarg.h>
 #include <string.h>
+#include <stdio.h>
 #include <float.h>
 #include <assert.h>
 #include <math.h>
 
 #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);
+    }
+
+}
+