FREQUENCIES BARCHART: Honour then PERCENT option
authorJohn Darrington <john@darrington.wattle.id.au>
Sat, 20 Feb 2016 12:12:06 +0000 (13:12 +0100)
committerJohn Darrington <john@darrington.wattle.id.au>
Sat, 20 Feb 2016 12:16:06 +0000 (13:16 +0100)
Fixes bug: #47180

src/language/stats/crosstabs.q
src/language/stats/frequencies.c
src/language/stats/graph.c
src/output/charts/barchart-cairo.c
src/output/charts/barchart.c
src/output/charts/barchart.h

index ab73f96ad5bea6b37bb481b488b39fdf33c79202..2edf248b2b0660ac82152d048995d7860758a5e7 100644 (file)
@@ -720,7 +720,7 @@ postcalc (struct crosstabs_proc *proc)
         }
       if (proc->barchart)
        chart_item_submit 
-         (barchart_create (pt->vars, pt->n_vars, _("Count"), pt->entries, pt->n_entries));
+         (barchart_create (pt->vars, pt->n_vars, _("Count"), false, pt->entries, pt->n_entries));
     }
 
   /* Free output and prepare for next split file. */
index 7b96f8d53d9b34b70f5cac2a5a69eceae2074372..dc18ed83c79589cf3c028cc872e84fb934dabfe8 100644 (file)
@@ -1477,7 +1477,8 @@ do_barchart(const struct frq_chart *bar, const struct variable **var,
   struct freq **slices = pick_cat_counts_ptr (bar, frq_tab, &n_slices);
 
   chart_item_submit (barchart_create (var, 1,
-                                     (bar->y_scale == FRQ_FREQ) ? _("Count") : _("Percent"),
+                                     (bar->y_scale == FRQ_FREQ) ? _("Count") : _("Percent"), 
+                                     (bar->y_scale == FRQ_PERCENT),
                                      slices, n_slices));
   free (slices);
 }
index a53a1913024cf41f5ac80d40be3a883a8c54a1e3..424091f9c5c9516816dca0fb1c29671420738141 100644 (file)
@@ -490,7 +490,7 @@ run_barchart (struct graph *cmd, struct casereader *input)
                     ag_func[cmd->agr].description);
       
     chart_item_submit (barchart_create (cmd->by_var, cmd->n_by_vars,
-                                       ds_cstr (&label),
+                                       ds_cstr (&label), false,
                                        freqs, n_freqs));
 
     ds_destroy (&label);
index 397715ff386d38884ce4ca9838ec39a1bb648c74..c3cc2f3ca14225c29875e5a8d28b6031345e371d 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2015 Free Software Foundation, Inc.
+   Copyright (C) 2015, 2016 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -67,7 +67,10 @@ xrchart_draw_barchart (const struct chart_item *chart_item, cairo_t *cr,
   xrchart_write_ylabel (cr, geom, bc->ylabel);
   xrchart_write_xlabel (cr, geom, chart_item_get_title (chart_item));
 
-  xrchart_write_yscale (cr, geom, 0, bc->largest);
+  if (bc->percent)
+    xrchart_write_yscale (cr, geom, 0, bc->largest * 100.0 / bc->total_count );
+  else
+    xrchart_write_yscale (cr, geom, 0, bc->largest);
 
   const double abscale = geom->axis[SCALE_ABSCISSA].data_max - geom->axis[SCALE_ABSCISSA].data_min;
   const double width = abscale / (double) (bc->n_nzcats + bc->n_pcats);
@@ -122,6 +125,8 @@ xrchart_draw_barchart (const struct chart_item *chart_item, cairo_t *cr,
   for (i = 0; i < bc->n_nzcats; i++)
     {
       double height = geom->axis[SCALE_ORDINATE].scale * bc->cats[i]->count;
+      if (bc->percent)
+       height *= 100.0  /  bc->total_count ;
 
       if (prev && !value_equal (prev, &bc->cats[i]->values[0], bc->widths[0]))
        {
index fea50b787e2fe6315bf35243567d09a43ff0d8c6..aca03ee8c41ad3320f11d499ddfd6fe52baf619a 100644 (file)
@@ -85,7 +85,7 @@ compare_freq_2level_ptr_3way (const void *a_, const void *b_, const void *bc_)
 */
 struct chart_item *
 barchart_create (const struct variable **var, int n_vars,
-                const char *ylabel, 
+                const char *ylabel, bool percent, 
                 struct freq *const *cats, int n_cats)
 {
   struct barchart *bar;
@@ -100,6 +100,7 @@ barchart_create (const struct variable **var, int n_vars,
   assert (n_vars >= 1);
 
   bar = xzalloc (sizeof *bar);
+  bar->percent = percent;
   bar->var = var;
   bar->n_vars = n_vars;
   bar->n_nzcats = n_cats;
@@ -220,6 +221,7 @@ barchart_create (const struct variable **var, int n_vars,
            if (0 == compare_freq_2level_ptr_3way (&foo, &c, bar))
              {
                foo->count += c->count;
+               bar->total_count += c->count;
                
                if (foo->count > bar->largest)
                  bar->largest = foo->count;
@@ -237,6 +239,7 @@ barchart_create (const struct variable **var, int n_vars,
            if (c->count > bar->largest)
              bar->largest = aggregated_freq->count;
            
+           bar->total_count += c->count;
            bar->cats[x++] = aggregated_freq;
          }
       }
index d47ce165bb24d641f67ced9f2dcf9ea0e260f903..b8b2122cb9b6bc9c50bad79d899553ef66d13359 100644 (file)
@@ -37,6 +37,9 @@ struct barchart
   {
     struct chart_item chart_item;
 
+    /* Should the chart be displayed as percentages */
+    bool percent;
+
     /* The categories */
     struct freq **cats;
 
@@ -49,6 +52,9 @@ struct barchart
     /* The largest count of all the categories */
     double largest;
 
+    /* The sum of all the counts */
+    double total_count;
+
     /* The label for the ordinate (vertical axis) */
     char *ylabel;
 
@@ -75,7 +81,7 @@ struct variable;
 struct freq;
 
 struct chart_item *barchart_create (const struct variable **, int n_vars,
-                                   const char *ylabel,
+                                   const char *ylabel, bool percent,
                                     struct freq *const *, int n_cats);
 \f
 /* This boilerplate for barchart, a subclass of chart_item, was