Fixed bug where an empty chart (one with no data) would crash.
[pspp] / src / output / charts / boxplot.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2004, 2008, 2009, 2011 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17
18 #include <config.h>
19
20 #include "output/charts/boxplot.h"
21
22 #include "math/box-whisker.h"
23 #include "output/chart-item-provider.h"
24
25 struct boxplot *
26 boxplot_create (double y_min, double y_max, const char *title)
27 {
28   if (y_min >= y_max)
29     return NULL;
30   struct boxplot *boxplot = xmalloc (sizeof *boxplot);
31   chart_item_init (&boxplot->chart_item, &boxplot_class, title);
32   boxplot->y_min = y_min;
33   boxplot->y_max = y_max;
34   boxplot->boxes = NULL;
35   boxplot->n_boxes = boxplot->boxes_allocated = 0;
36   return boxplot;
37 }
38
39 void
40 boxplot_add_box (struct boxplot *boxplot,
41                  struct box_whisker *bw, const char *label)
42 {
43   if (boxplot == NULL)
44     return;
45
46   struct boxplot_box *box;
47   if (boxplot->n_boxes >= boxplot->boxes_allocated)
48     boxplot->boxes = x2nrealloc (boxplot->boxes, &boxplot->boxes_allocated,
49                                  sizeof *boxplot->boxes);
50   box = &boxplot->boxes[boxplot->n_boxes++];
51   box->bw = bw;
52   box->label = xstrdup (label);
53 }
54
55 static void
56 boxplot_chart_destroy (struct chart_item *chart_item)
57 {
58   struct boxplot *boxplot = to_boxplot (chart_item);
59   if (boxplot == NULL)
60     return;
61
62   size_t i;
63
64   for (i = 0; i < boxplot->n_boxes; i++)
65     {
66       struct boxplot_box *box = &boxplot->boxes[i];
67       struct statistic *statistic = &box->bw->parent.parent;
68       statistic->destroy (statistic);
69       free (box->label);
70     }
71   free (boxplot->boxes);
72   free (boxplot);
73 }
74
75 const struct chart_item_class boxplot_class =
76   {
77     boxplot_chart_destroy
78   };