X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=src%2Foutput%2Fcharts%2Fbarchart.c;h=1b946fddffb780a0cd636eb8b3ff15742f4153f3;hb=142f8f8814423f76523825f8df060e2fa9d2a2b6;hp=cf88d66561cc3a50d40289e2688766f02e32178a;hpb=3dd0f6ae0d5eb73a2270a243e443c4ae03c2c16e;p=pspp diff --git a/src/output/charts/barchart.c b/src/output/charts/barchart.c index cf88d66561..1b946fddff 100644 --- a/src/output/charts/barchart.c +++ b/src/output/charts/barchart.c @@ -24,10 +24,11 @@ #include "libpspp/cast.h" #include "libpspp/str.h" #include "libpspp/array.h" -#include "output/chart-item-provider.h" +#include "output/chart-provider.h" #include "gl/xalloc.h" #include "data/variable.h" +#include "data/settings.h" #include "language/stats/freq.h" @@ -42,6 +43,19 @@ compare_category_3way (const void *a_, const void *b_, const void *bc_) } +static int +compare_category_by_index_3way (const void *a_, const void *b_, + const void *unused UNUSED) +{ + const struct category *const*a = a_; + const struct category *const*b = b_; + + if ( (*a)->idx < (*b)->idx) + return -1; + + return ((*a)->idx > (*b)->idx); +} + static unsigned int hash_freq_2level_ptr (const void *a_, const void *bc_) { @@ -72,6 +86,79 @@ compare_freq_2level_ptr_3way (const void *a_, const void *b_, const void *bc_) return level0; } +/* Print out a textual representation of a barchart. + This is intended only for testing, and not as a means + of visualising the data. +*/ +static void +barchart_dump (const struct barchart *bc, FILE *fp) +{ + fprintf (fp, "Graphic: Barchart\n"); + fprintf (fp, "Percentage: %d\n", bc->percent); + fprintf (fp, "Total Categories: %d\n", bc->n_nzcats); + fprintf (fp, "Primary Categories: %d\n", bc->n_pcats); + fprintf (fp, "Largest Category: %g\n", bc->largest); + fprintf (fp, "Total Count: %g\n", bc->total_count); + + fprintf (fp, "Y Label: \"%s\"\n", bc->ylabel); + + fprintf (fp, "Categorical Variables:\n"); + for (int i = 0; i < bc->n_vars; ++i) + { + fprintf (fp, " Var: \"%s\"\n", var_get_name (bc->var[i])); + } + + fprintf (fp, "Categories:\n"); + struct category *cat; + struct category **cats = XCALLOC (hmap_count (&bc->primaries), struct category *); + int i = 0; + HMAP_FOR_EACH (cat, struct category, node, &bc->primaries) + { + cats[i++] = cat; + } + /* HMAP_FOR_EACH is not guaranteed to iterate in any particular order. So + we must sort here before we output the results. */ + sort (cats, i, sizeof (struct category *), compare_category_by_index_3way, bc); + for (i = 0; i < hmap_count (&bc->primaries); ++i) + { + const struct category *c = cats[i]; + fprintf (fp, " %d \"%s\"\n", c->idx, ds_cstr (&c->label)); + } + free (cats); + + if (bc->ss) + { + fprintf (fp, "Sub-categories:\n"); + for (int i = 0; i < bc->n_nzcats / bc->n_pcats; ++i) + { + const struct category *cat = bc->ss[i]; + fprintf (fp, " %d \"%s\"\n", cat->idx, ds_cstr(&cat->label)); + } + } + + fprintf (fp, "All Categories:\n"); + for (int i = 0; i < bc->n_nzcats; ++i) + { + const struct freq *frq = bc->cats[i]; + fprintf (fp, "Count: %g; ", frq->count); + + struct string s = DS_EMPTY_INITIALIZER; + var_append_value_name (bc->var[0], &frq->values[0], &s); + + fprintf (fp, "Cat: \"%s\"", ds_cstr (&s)); + ds_clear (&s); + + if (bc->ss) + { + var_append_value_name (bc->var[1], &frq->values[1], &s); + fprintf (fp, ", \"%s\"", ds_cstr (&s)); + } + ds_destroy (&s); + fputc ('\n', fp); + } + + fputc ('\n', fp); +} /* Creates and returns a chart that will render a barchart with @@ -83,12 +170,11 @@ compare_freq_2level_ptr_3way (const void *a_, const void *b_, const void *bc_) CATS are the counts of the values of those variables. N_CATS is the number of distinct values. */ -struct chart_item * +struct chart * barchart_create (const struct variable **var, int n_vars, const char *ylabel, bool percent, struct freq *const *cats, int n_cats) { - struct barchart *bar; int i; const int pidx = 0; @@ -97,14 +183,14 @@ barchart_create (const struct variable **var, int n_vars, int width = var_get_width (var[pidx]); - assert (n_vars >= 1); + assert (n_vars >= 1 && n_vars <= 2); - bar = xzalloc (sizeof *bar); + struct barchart *bar = XZALLOC (struct barchart); bar->percent = percent; bar->var = var; bar->n_vars = n_vars; bar->n_nzcats = n_cats; - chart_item_init (&bar->chart_item, &barchart_class, var_to_string (var[pidx])); + chart_init (&bar->chart, &barchart_class, var_to_string (var[pidx])); bar->largest = -1; bar->ylabel = strdup (ylabel); @@ -135,7 +221,7 @@ barchart_create (const struct variable **var, int n_vars, if (!flag) { - struct category *s = xzalloc (sizeof *s); + struct category *s = XZALLOC (struct category); s->idx = idx++; s->width = var_get_width (var[pidx]); value_init (&s->val, s->width); @@ -173,7 +259,7 @@ barchart_create (const struct variable **var, int n_vars, if (!flag) { - struct category *s = xzalloc (sizeof *s); + struct category *s = XZALLOC (struct category); s->idx = idx++; s->width = var_get_width (var[sidx]); value_init (&s->val, s->width); @@ -251,7 +337,10 @@ barchart_create (const struct variable **var, int n_vars, sort (bar->cats, bar->n_nzcats, sizeof *bar->cats, compare_freq_2level_ptr_3way, bar); - return &bar->chart_item; + if (settings_get_testing_mode ()) + barchart_dump (bar, stdout); + + return &bar->chart; } static void @@ -271,9 +360,9 @@ destroy_cat_map (struct hmap *m) } static void -barchart_destroy (struct chart_item *chart_item) +barchart_destroy (struct chart *chart) { - struct barchart *bar = to_barchart (chart_item); + struct barchart *bar = to_barchart (chart); int i; @@ -294,7 +383,7 @@ barchart_destroy (struct chart_item *chart_item) free (bar); } -const struct chart_item_class barchart_class = +const struct chart_class barchart_class = { barchart_destroy };