2 * analysis-frequency.c:
5 * Andreas J. Guelzow <aguelzow@pyrshep.ca>
7 * (C) Copyright 2008 by Andreas J. Guelzow <aguelzow@pyrshep.ca>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <https://www.gnu.org/licenses/>.
24 #include <gnumeric-config.h>
25 #include <glib/gi18n-lib.h>
27 #include <tools/analysis-frequency.h>
28 #include <tools/analysis-tools.h>
34 #include <sheet-object-graph.h>
35 #include <goffice/goffice.h>
39 analysis_tool_frequency_engine_run (data_analysis_output_t
*dao
,
40 analysis_tools_data_frequency_t
*info
)
49 GnmFunc
*fd_rows
= NULL
;
50 GnmFunc
*fd_columns
= NULL
;
51 GnmFunc
*fd_exact
= NULL
;
53 fd_sum
= gnm_func_lookup_or_add_placeholder ("SUM");
54 gnm_func_inc_usage (fd_sum
);
55 fd_if
= gnm_func_lookup_or_add_placeholder ("IF");
56 gnm_func_inc_usage (fd_if
);
57 fd_index
= gnm_func_lookup_or_add_placeholder ("INDEX");
58 gnm_func_inc_usage (fd_index
);
59 fd_isblank
= gnm_func_lookup_or_add_placeholder ("ISBLANK");
60 gnm_func_inc_usage (fd_isblank
);
63 fd_exact
= gnm_func_lookup_or_add_placeholder ("EXACT");
64 gnm_func_inc_usage (fd_exact
);
66 if (info
->percentage
) {
67 fd_rows
= gnm_func_lookup_or_add_placeholder ("ROWS");
68 gnm_func_inc_usage (fd_rows
);
69 fd_columns
= gnm_func_lookup_or_add_placeholder ("COLUMNS");
70 gnm_func_inc_usage (fd_columns
);
74 dao_set_italic (dao
, 0, 0, 0, 1);
75 set_cell_text_col (dao
, 0, 0, _("/Frequency Table"
78 /* Setting up the categories */
80 if (info
->predetermined
) {
81 int row
= 2, i
, j
, i_h_limit
, i_w_limit
;
82 GnmExpr
const *expr_bin
;
85 range_init_value (&range
, info
->bin
);
86 i_h_limit
= range_height (&range
);
87 i_w_limit
= range_width (&range
);
88 i_limit
= i_h_limit
* i_w_limit
;
90 expr_bin
= gnm_expr_new_constant (info
->bin
);
92 for (i
= 1; i
<= i_h_limit
; i
++)
93 for (j
= 1; j
<= i_w_limit
; j
++) {
94 GnmExpr
const *expr_index
;
96 expr_index
= gnm_expr_new_funcall3
98 gnm_expr_copy (expr_bin
),
99 gnm_expr_new_constant (value_new_int (i
)),
100 gnm_expr_new_constant (value_new_int (j
)));
102 dao_set_cell_expr (dao
, 0, row
++,
103 gnm_expr_new_funcall3
105 gnm_expr_new_funcall1
107 gnm_expr_copy (expr_index
)),
108 gnm_expr_new_constant (value_new_string ("")),
111 gnm_expr_free (expr_bin
);
116 for (l
= info
->base
.input
, col
= 1; l
; col
++, l
= l
->next
) {
117 GnmValue
*val
= value_dup ((GnmValue
*)l
->data
);
118 GnmValue
*val_c
= NULL
;
119 GnmExpr
const *expr_count
;
120 GnmExpr
const *expr_data
;
121 GnmExpr
const *expr_if
;
125 dao_set_italic (dao
, col
, 1, col
, 1);
126 if (info
->base
.labels
) {
127 val_c
= value_dup (val
);
128 switch (info
->base
.group_by
) {
130 val
->v_range
.cell
.a
.col
++;
133 val
->v_range
.cell
.a
.row
++;
136 dao_set_cell_expr (dao
, col
, 1,
137 gnm_expr_new_funcall1 (fd_index
,
138 gnm_expr_new_constant (val_c
)));
142 switch (info
->base
.group_by
) {
144 txt
= g_strdup_printf (_("Row %d"), col
);
147 txt
= g_strdup_printf (_("Column %d"), col
);
150 txt
= g_strdup_printf (_("Area %d"), col
);
153 dao_set_cell (dao
, col
, 1, txt
);
157 expr_data
= gnm_expr_new_constant (val
);
160 expr_if
= gnm_expr_new_funcall2
161 (fd_exact
, gnm_expr_copy (expr_data
),
162 make_cellref (- col
, 0));
164 expr_if
= gnm_expr_new_binary
165 (gnm_expr_copy (expr_data
),
166 GNM_EXPR_OP_EQUAL
, make_cellref (- col
, 0));
168 expr_count
= gnm_expr_new_funcall1 (fd_sum
,
169 gnm_expr_new_funcall3
171 gnm_expr_new_constant (value_new_int (1)),
172 gnm_expr_new_constant (value_new_int (0))));
174 if (info
->percentage
) {
175 dao_set_format (dao
, col
, 2, col
, i_limit
+ 2, "0.0%");
176 expr_count
= gnm_expr_new_binary (expr_count
,
179 (gnm_expr_new_funcall1
180 (fd_rows
, gnm_expr_copy (expr_data
)),
182 gnm_expr_new_funcall1
183 (fd_columns
, expr_data
)));
185 gnm_expr_free (expr_data
);
187 for (i
= 0; i
< i_limit
; i
++, row
++)
188 dao_set_cell_array_expr (dao
, col
, row
, gnm_expr_copy (expr_count
));
190 gnm_expr_free (expr_count
);
193 gnm_func_dec_usage (fd_if
);
194 gnm_func_dec_usage (fd_sum
);
195 gnm_func_dec_usage (fd_index
);
196 gnm_func_dec_usage (fd_isblank
);
198 gnm_func_dec_usage (fd_rows
);
199 if (fd_columns
!= NULL
)
200 gnm_func_dec_usage (fd_columns
);
201 if (fd_exact
!= NULL
)
202 gnm_func_dec_usage (fd_exact
);
204 /* Create Chart if requested */
205 if (info
->chart
!= NO_CHART
) {
215 graph
= g_object_new (GOG_TYPE_GRAPH
, NULL
);
216 chart
= GOG_CHART (gog_object_add_by_name (
217 GOG_OBJECT (graph
), "Chart", NULL
));
218 plot
= gog_plot_new_by_name ("GogBarColPlot");
219 if (info
->chart
== BAR_CHART
)
220 go_object_toggle (plot
, "horizontal");
221 gog_object_add_by_name (GOG_OBJECT (chart
),
222 "Plot", GOG_OBJECT (plot
));
224 cats
= dao_go_data_vector (dao
, 0, 2,
227 for (ct
= 1; ct
< col
; ct
++) {
229 values
= dao_go_data_vector (dao
, ct
, 2,
232 series
= gog_plot_new_series (plot
);
233 gog_series_set_dim (series
, 0, cats
, NULL
);
234 gog_series_set_dim (series
, 1, values
, NULL
);
236 g_object_unref (cats
);
238 so
= sheet_object_graph_new (graph
);
239 g_object_unref (graph
);
241 dao_set_sheet_object (dao
, 0, 1, so
);
244 dao_redraw_respan (dao
);
251 calc_length (GnmValue
*bin
)
253 g_return_val_if_fail (bin
!= NULL
, 0);
254 g_return_val_if_fail (VALUE_IS_CELLRANGE (bin
), 0);
256 return ((bin
->v_range
.cell
.b
.col
- bin
->v_range
.cell
.a
.col
+ 1) *
257 (bin
->v_range
.cell
.b
.row
- bin
->v_range
.cell
.a
.row
+ 1));
262 analysis_tool_frequency_engine (G_GNUC_UNUSED GOCmdContext
*gcc
, data_analysis_output_t
*dao
, gpointer specs
,
263 analysis_tool_engine_t selector
, gpointer result
)
265 analysis_tools_data_frequency_t
*info
= specs
;
268 case TOOL_ENGINE_UPDATE_DESCRIPTOR
:
269 return (dao_command_descriptor (dao
, _("Frequency Table (%s)"), result
)
271 case TOOL_ENGINE_UPDATE_DAO
:
275 prepare_input_range (&info
->base
.input
, info
->base
.group_by
);
277 i
= 2 + ((info
->predetermined
) ? calc_length (info
->bin
) : info
->n
);
279 dao_adjust (dao
, g_slist_length (info
->base
.input
) + 1, i
);
283 case TOOL_ENGINE_CLEAN_UP
:
284 return analysis_tool_generic_clean (specs
);
285 case TOOL_ENGINE_LAST_VALIDITY_CHECK
:
287 case TOOL_ENGINE_PREPARE_OUTPUT_RANGE
:
288 dao_prepare_output (NULL
, dao
, _("Frequency Table"));
290 case TOOL_ENGINE_FORMAT_OUTPUT_RANGE
:
291 return dao_format_output (dao
, _("Frequency Table"));
292 case TOOL_ENGINE_PERFORM_CALC
:
294 return analysis_tool_frequency_engine_run (dao
, specs
);