1
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3
* analysis-frequency.c:
6
* Andreas J. Guelzow <aguelzow@pyrshep.ca>
8
* (C) Copyright 2008 by Andreas J. Guelzow <aguelzow@pyrshep.ca>
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.
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.
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.
26
#include <gnumeric-config.h>
27
#include <glib/gi18n-lib.h>
29
#include "analysis-frequency.h"
30
#include "analysis-tools.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>
45
analysis_tool_frequency_engine_run (data_analysis_output_t *dao,
46
analysis_tools_data_frequency_t *info)
55
GnmFunc *fd_rows = NULL;
56
GnmFunc *fd_columns = NULL;
57
GnmFunc *fd_exact = NULL;
59
fd_sum = gnm_func_lookup ("SUM", NULL);
60
gnm_func_ref (fd_sum);
61
fd_if = gnm_func_lookup ("IF", NULL);
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);
69
fd_exact = gnm_func_lookup ("EXACT", NULL);
70
gnm_func_ref (fd_exact);
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);
80
dao_set_italic (dao, 0, 0, 0, 0);
81
set_cell_text_col (dao, 0, 0, _("/Frequency Table"
84
/* Setting up the categories */
86
if (info->predetermined) {
87
int row = 2, i, j, i_h_limit, i_w_limit;
88
GnmExpr const *expr_bin;
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;
96
expr_bin = gnm_expr_new_constant (info->bin);
98
for (i = 1; i <= i_h_limit; i++)
99
for (j = 1; j <= i_w_limit; j++) {
100
GnmExpr const *expr_index;
102
expr_index = gnm_expr_new_funcall3
104
gnm_expr_copy (expr_bin),
105
gnm_expr_new_constant (value_new_int (i)),
106
gnm_expr_new_constant (value_new_int (j)));
108
dao_set_cell_expr (dao, 0, row++,
109
gnm_expr_new_funcall3
111
gnm_expr_new_funcall1
113
gnm_expr_copy (expr_index)),
114
gnm_expr_new_constant (value_new_string ("")),
117
gnm_expr_free (expr_bin);
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;
131
if (info->base.labels) {
132
val_c = value_dup (val);
133
switch (info->base.group_by) {
135
val->v_range.cell.a.col++;
138
val->v_range.cell.a.row++;
141
dao_set_cell_expr (dao, col, 1,
142
gnm_expr_new_funcall1 (fd_index,
143
gnm_expr_new_constant (val_c)));
147
switch (info->base.group_by) {
149
format = _("Row %d");
152
format = _("Column %d");
155
format = _("Area %d");
158
dao_set_cell_printf (dao, col, 1, format, col);
161
expr_data = gnm_expr_new_constant (val);
164
expr_if = gnm_expr_new_funcall2
165
(fd_exact, gnm_expr_copy (expr_data),
166
make_cellref (- col, 0));
168
expr_if = gnm_expr_new_binary
169
(gnm_expr_copy (expr_data),
170
GNM_EXPR_OP_EQUAL, make_cellref (- col, 0));
172
expr_count = gnm_expr_new_funcall1 (fd_sum,
173
gnm_expr_new_funcall3
175
gnm_expr_new_constant (value_new_int (1)),
176
gnm_expr_new_constant (value_new_int (0))));
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,
183
(gnm_expr_new_funcall1
184
(fd_rows, gnm_expr_copy (expr_data)),
186
gnm_expr_new_funcall1
187
(fd_columns, expr_data)));
189
gnm_expr_free (expr_data);
191
for (i = 0; i < i_limit; i++, row++)
192
dao_set_cell_array_expr (dao, col, row, gnm_expr_copy (expr_count));
194
gnm_expr_free (expr_count);
197
gnm_func_unref (fd_if);
198
gnm_func_unref (fd_sum);
199
gnm_func_unref (fd_index);
200
gnm_func_unref (fd_isblank);
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);
208
/* Create Chart if requested */
209
if (info->chart != NO_CHART) {
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));
228
cats = dao_go_data_vector (dao, 0, 2,
231
for (ct = 1; ct < col; ct ++) {
233
values = dao_go_data_vector (dao, ct, 2,
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);
240
g_object_unref (cats);
242
so = sheet_object_graph_new (graph);
243
g_object_unref (graph);
245
dao_set_sheet_object (dao, 0, 1, so);
248
dao_redraw_respan (dao);
255
calc_length (GnmValue *bin)
257
g_return_val_if_fail (bin != NULL, 0);
258
g_return_val_if_fail (bin->type == VALUE_CELLRANGE, 0);
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));
266
analysis_tool_frequency_engine (data_analysis_output_t *dao, gpointer specs,
267
analysis_tool_engine_t selector, gpointer result)
269
analysis_tools_data_frequency_t *info = specs;
272
case TOOL_ENGINE_UPDATE_DESCRIPTOR:
273
return (dao_command_descriptor (dao, _("Frequency Table (%s)"), result)
275
case TOOL_ENGINE_UPDATE_DAO:
279
prepare_input_range (&info->base.input, info->base.group_by);
281
i = 2 + ((info->predetermined) ? calc_length (info->bin) : info->n);
283
dao_adjust (dao, g_slist_length (info->base.input) + 1, i);
287
case TOOL_ENGINE_CLEAN_UP:
288
return analysis_tool_generic_clean (specs);
289
case TOOL_ENGINE_LAST_VALIDITY_CHECK:
291
case TOOL_ENGINE_PREPARE_OUTPUT_RANGE:
292
dao_prepare_output (NULL, dao, _("Frequency Table"));
294
case TOOL_ENGINE_FORMAT_OUTPUT_RANGE:
295
return dao_format_output (dao, _("Frequency Table"));
296
case TOOL_ENGINE_PERFORM_CALC:
298
return analysis_tool_frequency_engine_run (dao, specs);