~ubuntu-branches/ubuntu/quantal/gnumeric/quantal

« back to all changes in this revision

Viewing changes to src/tools/analysis-frequency.c

  • Committer: Bazaar Package Importer
  • Author(s): Gauvain Pocentek
  • Date: 2009-06-07 11:10:47 UTC
  • mfrom: (1.1.19 upstream) (2.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090607111047-l3rtbzfjxvmi1kx0
Tags: 1.9.8-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Promoted gnumeric-doc to Recommends in gnumeric package for help to be
    installed automatically
  - gnumeric-gtk is a transitional package
  - gnumeric conflicts with gnumeric-gtk << 1.8.3-3ubuntu1
  - call initltool-update in po*
  - remove psiconv support (psiconv is in universe):
    o debian/control: remove B-D on libpsiconv-dev
    o debian/rules: don't pass --with-psiconv to ./configure

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
2
/*
 
3
 * analysis-frequency.c:
 
4
 *
 
5
 * Author:
 
6
 *   Andreas J. Guelzow  <aguelzow@pyrshep.ca>
 
7
 *
 
8
 * (C) Copyright 2008 by Andreas J. Guelzow  <aguelzow@pyrshep.ca>
 
9
 *
 
10
 *
 
11
 * This program is free software; you can redistribute it and/or modify
 
12
 * it under the terms of the GNU General Public License as published by
 
13
 * the Free Software Foundation; either version 2 of the License, or
 
14
 * (at your option) any later version.
 
15
 *
 
16
 * This program is distributed in the hope that it will be useful,
 
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
 * GNU General Public License for more details.
 
20
 *
 
21
 * You should have received a copy of the GNU General Public License
 
22
 * along with this program; if not, write to the Free Software
 
23
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
24
 */
 
25
 
 
26
#include <gnumeric-config.h>
 
27
#include <glib/gi18n-lib.h>
 
28
#include "gnumeric.h"
 
29
#include "analysis-frequency.h"
 
30
#include "analysis-tools.h"
 
31
#include "value.h"
 
32
#include "ranges.h"
 
33
#include "expr.h"
 
34
#include "func.h"
 
35
#include "numbers.h"
 
36
#include "sheet-object-graph.h"
 
37
#include <goffice/graph/gog-graph.h>
 
38
#include <goffice/graph/gog-object.h>
 
39
#include <goffice/graph/gog-chart.h>
 
40
#include <goffice/graph/gog-plot.h>
 
41
#include <goffice/graph/gog-series.h>
 
42
#include <goffice/utils/go-glib-extras.h>
 
43
 
 
44
static gboolean
 
45
analysis_tool_frequency_engine_run (data_analysis_output_t *dao,
 
46
                                    analysis_tools_data_frequency_t *info)
 
47
{
 
48
        gint i_limit, col;
 
49
        GSList *l;
 
50
 
 
51
        GnmFunc *fd_sum;
 
52
        GnmFunc *fd_if;
 
53
        GnmFunc *fd_index;
 
54
        GnmFunc *fd_isblank;
 
55
        GnmFunc *fd_rows = NULL;
 
56
        GnmFunc *fd_columns = NULL;
 
57
        GnmFunc *fd_exact = NULL;
 
58
 
 
59
        fd_sum = gnm_func_lookup ("SUM", NULL);
 
60
        gnm_func_ref (fd_sum);
 
61
        fd_if = gnm_func_lookup ("IF", NULL);
 
62
        gnm_func_ref (fd_if);
 
63
        fd_index = gnm_func_lookup ("INDEX", NULL);
 
64
        gnm_func_ref (fd_index);
 
65
        fd_isblank = gnm_func_lookup ("ISBLANK", NULL);
 
66
        gnm_func_ref (fd_isblank);
 
67
        
 
68
        if (info->exact) {
 
69
                fd_exact = gnm_func_lookup ("EXACT", NULL);
 
70
                gnm_func_ref (fd_exact);
 
71
        }
 
72
        if (info->percentage) {
 
73
                fd_rows = gnm_func_lookup ("ROWS", NULL);
 
74
                gnm_func_ref (fd_rows);
 
75
                fd_columns = gnm_func_lookup ("COLUMNS", NULL);
 
76
                gnm_func_ref (fd_columns);
 
77
        }
 
78
        /* General Info */
 
79
 
 
80
        dao_set_italic (dao, 0, 0, 0, 0);
 
81
        set_cell_text_col (dao, 0, 0, _("/Frequency Table"
 
82
                                        "/Category"));
 
83
 
 
84
        /* Setting up the categories */
 
85
 
 
86
        if (info->predetermined) {
 
87
                int row = 2, i, j, i_h_limit, i_w_limit;
 
88
                GnmExpr const *expr_bin;
 
89
                GnmRange range;
 
90
                
 
91
                range_init_value (&range, info->bin);
 
92
                i_h_limit = range_height (&range);
 
93
                i_w_limit = range_width (&range);
 
94
                i_limit = i_h_limit * i_w_limit;
 
95
 
 
96
                expr_bin = gnm_expr_new_constant (info->bin);
 
97
 
 
98
                for (i = 1; i <= i_h_limit; i++)
 
99
                        for (j = 1; j <= i_w_limit; j++) {
 
100
                                GnmExpr const *expr_index;
 
101
 
 
102
                                expr_index =  gnm_expr_new_funcall3
 
103
                                        (fd_index,
 
104
                                         gnm_expr_copy (expr_bin),
 
105
                                         gnm_expr_new_constant (value_new_int (i)),
 
106
                                         gnm_expr_new_constant (value_new_int (j)));
 
107
                                
 
108
                                dao_set_cell_expr (dao, 0, row++,
 
109
                                                   gnm_expr_new_funcall3
 
110
                                                   (fd_if,
 
111
                                                    gnm_expr_new_funcall1
 
112
                                                    (fd_isblank,
 
113
                                                     gnm_expr_copy (expr_index)),
 
114
                                                    gnm_expr_new_constant (value_new_string ("")),
 
115
                                                    expr_index));
 
116
                        }
 
117
                gnm_expr_free (expr_bin);
 
118
        } else {
 
119
                i_limit = info->n;
 
120
        }
 
121
        
 
122
        for (l = info->base.input, col = 1; l; col++, l = l->next) {
 
123
                GnmValue *val = value_dup ((GnmValue *)l->data);
 
124
                GnmValue *val_c = NULL;
 
125
                GnmExpr const *expr_count;
 
126
                GnmExpr const *expr_data;
 
127
                GnmExpr const *expr_if;
 
128
                int i, row = 2;
 
129
 
 
130
                
 
131
                if (info->base.labels) {
 
132
                        val_c = value_dup (val);
 
133
                        switch (info->base.group_by) {
 
134
                        case GROUPED_BY_ROW:
 
135
                                val->v_range.cell.a.col++;
 
136
                                break;
 
137
                        default:
 
138
                                val->v_range.cell.a.row++;
 
139
                                break;
 
140
                        }
 
141
                        dao_set_cell_expr (dao, col, 1,
 
142
                                           gnm_expr_new_funcall1 (fd_index,
 
143
                                                                  gnm_expr_new_constant (val_c)));
 
144
                } else {
 
145
                        char const *format;
 
146
                        
 
147
                        switch (info->base.group_by) {
 
148
                        case GROUPED_BY_ROW:
 
149
                                format = _("Row %d");
 
150
                                break;
 
151
                        case GROUPED_BY_COL:
 
152
                                format = _("Column %d");
 
153
                                break;
 
154
                        default:
 
155
                                format = _("Area %d");
 
156
                                break;
 
157
                        }
 
158
                        dao_set_cell_printf (dao, col, 1, format, col);
 
159
                }
 
160
 
 
161
                expr_data = gnm_expr_new_constant (val);
 
162
                
 
163
                if (info->exact)
 
164
                        expr_if = gnm_expr_new_funcall2 
 
165
                                (fd_exact, gnm_expr_copy (expr_data), 
 
166
                                 make_cellref (- col, 0));
 
167
                else
 
168
                        expr_if = gnm_expr_new_binary
 
169
                                (gnm_expr_copy (expr_data),
 
170
                                 GNM_EXPR_OP_EQUAL, make_cellref (- col, 0));
 
171
 
 
172
                expr_count = gnm_expr_new_funcall1 (fd_sum,  
 
173
                                                    gnm_expr_new_funcall3
 
174
                                                    (fd_if, expr_if,
 
175
                                                     gnm_expr_new_constant (value_new_int (1)),
 
176
                                                     gnm_expr_new_constant (value_new_int (0))));
 
177
 
 
178
                if (info->percentage) {
 
179
                        dao_set_format  (dao, col, 2, col, i_limit + 2, "0.0%");
 
180
                        expr_count = gnm_expr_new_binary (expr_count,
 
181
                                                          GNM_EXPR_OP_DIV,
 
182
                                                          gnm_expr_new_binary 
 
183
                                                          (gnm_expr_new_funcall1
 
184
                                                           (fd_rows, gnm_expr_copy (expr_data)),
 
185
                                                           GNM_EXPR_OP_MULT,
 
186
                                                          gnm_expr_new_funcall1
 
187
                                                           (fd_columns, expr_data)));
 
188
                } else
 
189
                        gnm_expr_free (expr_data);
 
190
 
 
191
                for (i = 0; i < i_limit; i++, row++)
 
192
                        dao_set_cell_array_expr (dao, col, row, gnm_expr_copy (expr_count));
 
193
                
 
194
                gnm_expr_free (expr_count);
 
195
        }
 
196
 
 
197
        gnm_func_unref (fd_if);
 
198
        gnm_func_unref (fd_sum);
 
199
        gnm_func_unref (fd_index);
 
200
        gnm_func_unref (fd_isblank);
 
201
        if (fd_rows != NULL)
 
202
                gnm_func_unref (fd_rows);
 
203
        if (fd_columns != NULL)
 
204
                gnm_func_unref (fd_columns);
 
205
        if (fd_exact != NULL)
 
206
                gnm_func_unref (fd_exact);
 
207
 
 
208
        /* Create Chart if requested */
 
209
        if (info->chart != NO_CHART) {
 
210
                SheetObject *so;
 
211
                GogGraph     *graph;
 
212
                GogChart     *chart;
 
213
                GogPlot      *plot;
 
214
                GogSeries    *series;
 
215
                GOData *cats;
 
216
                GOData *values;
 
217
                int ct;
 
218
                
 
219
                graph = g_object_new (GOG_TYPE_GRAPH, NULL);
 
220
                chart = GOG_CHART (gog_object_add_by_name (
 
221
                                                   GOG_OBJECT (graph), "Chart", NULL));
 
222
                plot = gog_plot_new_by_name ("GogBarColPlot");
 
223
                if (info->chart == BAR_CHART)
 
224
                        go_object_toggle (plot, "horizontal");
 
225
                gog_object_add_by_name (GOG_OBJECT (chart),
 
226
                                        "Plot", GOG_OBJECT (plot));
 
227
                
 
228
                cats = dao_go_data_vector (dao, 0, 2,
 
229
                                             0, 2 + i_limit);
 
230
 
 
231
                for (ct = 1; ct < col; ct ++) {
 
232
                        g_object_ref (cats);
 
233
                        values = dao_go_data_vector (dao, ct, 2,
 
234
                                                     ct, 2 + i_limit);
 
235
                        
 
236
                        series = gog_plot_new_series (plot);
 
237
                        gog_series_set_dim (series, 0, cats, NULL);
 
238
                        gog_series_set_dim (series, 1, values, NULL);
 
239
                }
 
240
                g_object_unref (cats);
 
241
 
 
242
                so = sheet_object_graph_new (graph);
 
243
                g_object_unref (graph);
 
244
                
 
245
                dao_set_sheet_object (dao, 0, 1, so);
 
246
        }
 
247
 
 
248
        dao_redraw_respan (dao);
 
249
 
 
250
        return FALSE;
 
251
}
 
252
 
 
253
 
 
254
static gint
 
255
calc_length (GnmValue   *bin)
 
256
{
 
257
        g_return_val_if_fail (bin != NULL, 0);
 
258
        g_return_val_if_fail (bin->type == VALUE_CELLRANGE, 0);
 
259
 
 
260
        return ((bin->v_range.cell.b.col - bin->v_range.cell.a.col + 1) *
 
261
                (bin->v_range.cell.b.row - bin->v_range.cell.a.row + 1));
 
262
}
 
263
 
 
264
 
 
265
gboolean
 
266
analysis_tool_frequency_engine (data_analysis_output_t *dao, gpointer specs,
 
267
                              analysis_tool_engine_t selector, gpointer result)
 
268
{
 
269
        analysis_tools_data_frequency_t *info = specs;
 
270
 
 
271
        switch (selector) {
 
272
        case TOOL_ENGINE_UPDATE_DESCRIPTOR:
 
273
                return (dao_command_descriptor (dao, _("Frequency Table (%s)"), result)
 
274
                        == NULL);
 
275
        case TOOL_ENGINE_UPDATE_DAO:
 
276
        {
 
277
                int i;
 
278
 
 
279
                prepare_input_range (&info->base.input, info->base.group_by);
 
280
 
 
281
                i = 2 + ((info->predetermined) ? calc_length (info->bin) : info->n);
 
282
 
 
283
                dao_adjust (dao, g_slist_length (info->base.input) + 1, i);
 
284
 
 
285
                return FALSE;
 
286
        }
 
287
        case TOOL_ENGINE_CLEAN_UP:
 
288
                return analysis_tool_generic_clean (specs);
 
289
        case TOOL_ENGINE_LAST_VALIDITY_CHECK:
 
290
                return FALSE;
 
291
        case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:
 
292
                dao_prepare_output (NULL, dao, _("Frequency Table"));
 
293
                return FALSE;
 
294
        case TOOL_ENGINE_FORMAT_OUTPUT_RANGE:
 
295
                return dao_format_output (dao, _("Frequency Table"));
 
296
        case TOOL_ENGINE_PERFORM_CALC:
 
297
        default:
 
298
                return analysis_tool_frequency_engine_run (dao, specs);
 
299
        }
 
300
        return TRUE;
 
301
}
 
302
 
 
303
 
 
304
 
 
305