gnumeric r16964 - in trunk: . src/dialogs src/tools
- From: guelzow svn gnome org
- To: svn-commits-list gnome org
- Subject: gnumeric r16964 - in trunk: . src/dialogs src/tools
- Date: Fri, 14 Nov 2008 07:36:31 +0000 (UTC)
Author: guelzow
Date: Fri Nov 14 07:36:31 2008
New Revision: 16964
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16964&view=rev
Log:
2008-11-11 Andreas J. Guelzow <aguelzow pyrshep ca>
* kaplan-meier.glade: add groups tab
* dialog-analysis-tool-kaplan-meier.c (KaplanMeierToolState): add new
fields
(kaplan_meier_tool_update_sensitivity_cb): handle new tab
(kaplan_meier_tool_get_groups_cb): new
(kaplan_meier_tool_get_groups): new
(kaplan_meier_tool_ok_clicked_cb): handle new tab
(cb_group_name_edited): new
(cb_change_from): new
(cb_selection_changed): new
(kaplan_meier_tool_update_groups_sensitivity_cb): new
(dialog_kaplan_meier_tool_treeview_add_item): new
(dialog_kaplan_meier_tool_setup_treeview): new
(kaplan_meier_tool_add_group_cb): new
(kaplan_meier_tool_remove_group_cb): new
(dialog_kaplan_meier_tool): handle new tab
2008-11-14 Andreas J. Guelzow <aguelzow pyrshep ca>
* analysis-kaplan-meier.c (analysis_tool_kaplan_meier_engine_run):
handle multiple groups
(analysis_tool_kaplan_meier_clear_gl_cb): new
(analysis_tool_kaplan_meier_engine): properly dispose of all data
* analysis-kaplan-meier.h (analysis_tools_data_kaplan_meier_t): add
new fields
(analysis_tools_kaplan_meier_group_t): new
Modified:
trunk/NEWS
trunk/src/dialogs/ChangeLog
trunk/src/dialogs/dialog-analysis-tool-kaplan-meier.c
trunk/src/dialogs/dialog-analysis-tools.c
trunk/src/dialogs/kaplan-meier.glade
trunk/src/tools/ChangeLog
trunk/src/tools/analysis-kaplan-meier.c
trunk/src/tools/analysis-kaplan-meier.h
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Fri Nov 14 07:36:31 2008
@@ -7,7 +7,8 @@
* Permit lexicographic sorting by sheet names in the manage sheets
dialog [#527076]
* Add functional seealso links in the function browser
- * Allow ranges of censor marks in Kaplan-Meier tool [#558582]
+ * Allow ranges of censor marks in Kaplan-Meier tool and
+ multiple groups [#558582]
Hib Eris:
* Fix problems with toolbars when no handle bar present. [#559249]
Modified: trunk/src/dialogs/dialog-analysis-tool-kaplan-meier.c
==============================================================================
--- trunk/src/dialogs/dialog-analysis-tool-kaplan-meier.c (original)
+++ trunk/src/dialogs/dialog-analysis-tool-kaplan-meier.c Fri Nov 14 07:36:31 2008
@@ -52,10 +52,7 @@
#include <glade/glade.h>
#include <string.h>
-#include <gtk/gtktable.h>
-#include <gtk/gtktogglebutton.h>
-#include <gtk/gtkspinbutton.h>
-#include <gtk/gtklabel.h>
+#include <gtk/gtk.h>
#define KAPLAN_MEIER_KEY "analysistools-kaplan-meier-dialog"
@@ -66,9 +63,27 @@
GtkWidget *censor_spin_to;
GtkWidget *graph_button;
GtkWidget *tick_button;
+ GtkWidget *add_group_button;
+ GtkWidget *remove_group_button;
GtkWidget *std_error_button;
+ GtkWidget *groups_check;
+ GtkWidget *groups_table;
+ GnmExprEntry *groups_input;
+ GtkTreeView *groups_treeview;
+ GtkListStore *groups_list;
} KaplanMeierToolState;
+enum
+{
+ GROUP_NAME,
+ GROUP_FROM,
+ GROUP_TO,
+ GROUP_ADJUSTMENT_FROM,
+ GROUP_ADJUSTMENT_TO,
+ GROUP_COLUMNS
+};
+
+
/**
* kaplan_meier_tool_update_sensitivity_cb:
* @dummy:
@@ -81,12 +96,15 @@
KaplanMeierToolState *state)
{
gboolean censorship;
+ gboolean groups;
GnmValue *input_range;
GnmValue *input_range_2 = NULL;
int height, width;
censorship = gtk_toggle_button_get_active (
GTK_TOGGLE_BUTTON (state->censorship_button));
+ groups = gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (state->groups_check));
gtk_widget_set_sensitive (state->tick_button, censorship);
@@ -138,6 +156,34 @@
value_release (input_range_2);
}
+
+ if (groups) {
+ input_range_2 = gnm_expr_entry_parse_as_value
+ (GNM_EXPR_ENTRY (state->groups_input), state->base.sheet);
+
+ if (input_range_2 == NULL) {
+ gtk_label_set_text (GTK_LABEL (state->base.warning),
+ _("The groups column is not valid."));
+ gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+ return;
+ }
+ if (input_range_2->v_range.cell.b.col != input_range_2->v_range.cell.a.col) {
+ gtk_label_set_text (GTK_LABEL (state->base.warning),
+ _("The groups column should be part of a single column."));
+ gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+ value_release (input_range_2);
+ return;
+ }
+ if (input_range_2->v_range.cell.b.row - input_range_2->v_range.cell.a.row != height) {
+ gtk_label_set_text (GTK_LABEL (state->base.warning),
+ _("The groups and time columns should have the same height."));
+ gtk_widget_set_sensitive (state->base.ok_button, FALSE);
+ value_release (input_range_2);
+ return;
+ }
+
+ value_release (input_range_2);
+ }
if (!gnm_dao_is_ready (GNM_DAO (state->base.gdao))) {
gtk_label_set_text (GTK_LABEL (state->base.warning),
@@ -153,6 +199,37 @@
return;
}
+static gboolean
+kaplan_meier_tool_get_groups_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
+ gpointer data)
+{
+ GSList **list = data;
+ analysis_tools_kaplan_meier_group_t *group_item = g_new0 (analysis_tools_kaplan_meier_group_t, 1);
+
+ gtk_tree_model_get (model, iter,
+ GROUP_NAME, &(group_item->name),
+ GROUP_FROM, &(group_item->group_from),
+ GROUP_TO, &(group_item->group_to),
+ -1);
+ *list = g_slist_prepend (*list, group_item);
+
+ return FALSE;
+}
+
+static GSList *
+kaplan_meier_tool_get_groups (KaplanMeierToolState *state)
+{
+ GSList *list = NULL;
+
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state->groups_check)))
+ return NULL;
+
+ gtk_tree_model_foreach (GTK_TREE_MODEL (state->groups_list),
+ kaplan_meier_tool_get_groups_cb,
+ &list);
+ return g_slist_reverse (list);
+}
+
/**
* kaplan_meier_tool_ok_clicked_cb:
* @button:
@@ -193,6 +270,10 @@
data->censor_mark = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (state->censor_spin_from));
data->censor_mark_to = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (state->censor_spin_to));
+ data->group_list = kaplan_meier_tool_get_groups (state);
+ data->range_3 = ((data->group_list == NULL) ? NULL : gnm_expr_entry_parse_as_value
+ (GNM_EXPR_ENTRY (state->groups_input), state->base.sheet));
+
data->chart = gtk_toggle_button_get_active (
GTK_TOGGLE_BUTTON (state->graph_button));
data->ticks = gtk_toggle_button_get_active (
@@ -239,6 +320,17 @@
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->censorship_button), TRUE);
return FALSE;
}
+
+static gboolean
+kaplan_meier_tool_set_groups_cb (G_GNUC_UNUSED GtkWidget *widget,
+ G_GNUC_UNUSED GdkEventFocus *event,
+ KaplanMeierToolState *state)
+{
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->groups_check), TRUE);
+ return FALSE;
+}
+
+
static gboolean
kaplan_meier_tool_set_censor_from_cb (G_GNUC_UNUSED GtkWidget *dummy,
KaplanMeierToolState *state)
@@ -258,6 +350,226 @@
return FALSE;
}
+static void
+cb_group_name_edited (GtkCellRendererText *cell,
+ gchar *path_string,
+ gchar *new_text,
+ KaplanMeierToolState *state)
+{
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ if (cell != NULL) {
+ path = gtk_tree_path_new_from_string (path_string);
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (state->groups_list),
+ &iter, path))
+ gtk_list_store_set (state->groups_list, &iter,
+ GROUP_NAME, new_text, -1);
+ else
+ g_warning ("Did not get a valid iterator");
+ gtk_tree_path_free (path);
+ }
+}
+
+static void
+cb_change_to (GtkCellRendererText *cell,
+ gchar *path_string,
+ gchar *new_text,
+ KaplanMeierToolState *state)
+{
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ guint val = (guint) (atoi (new_text));
+
+ if (cell != NULL) {
+ path = gtk_tree_path_new_from_string (path_string);
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (state->groups_list),
+ &iter, path))
+ gtk_list_store_set (state->groups_list, &iter,
+ GROUP_TO, val, -1);
+ else
+ g_warning ("Did not get a valid iterator");
+ gtk_tree_path_free (path);
+ }
+}
+
+static void
+cb_change_from (GtkCellRendererText *cell,
+ gchar *path_string,
+ gchar *new_text,
+ KaplanMeierToolState *state)
+{
+ if (cell != NULL) {
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ guint val = (guint) (atoi (new_text));
+ guint old_to;
+ GtkObject *adjustment_to;
+
+
+ path = gtk_tree_path_new_from_string (path_string);
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (state->groups_list),
+ &iter, path))
+ gtk_list_store_set (state->groups_list, &iter,
+ GROUP_FROM, val,
+ -1);
+ else
+ g_warning ("Did not get a valid iterator");
+ gtk_tree_path_free (path);
+
+ gtk_tree_model_get (GTK_TREE_MODEL (state->groups_list), &iter,
+ GROUP_TO, &old_to,
+ GROUP_ADJUSTMENT_TO, &adjustment_to,
+ -1);
+
+ if (old_to < val)
+ gtk_list_store_set (state->groups_list, &iter,
+ GROUP_TO, val,
+ -1);
+ g_object_set (G_OBJECT (adjustment_to), "lower", (gdouble) val, NULL);
+
+ }
+}
+
+static void
+cb_selection_changed (GtkTreeSelection *selection,
+ KaplanMeierToolState *state)
+{
+ gtk_widget_set_sensitive (state->remove_group_button,
+ gtk_tree_selection_get_selected (selection, NULL, NULL));
+}
+
+static void
+kaplan_meier_tool_update_groups_sensitivity_cb (G_GNUC_UNUSED GtkWidget *dummy,
+ KaplanMeierToolState *state)
+{
+ gboolean groups = gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (state->groups_check));
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (state->groups_treeview);
+
+ gtk_widget_set_sensitive (state->add_group_button, groups);
+ gtk_widget_set_sensitive (GTK_WIDGET (state->groups_treeview), groups);
+
+ if (groups)
+ cb_selection_changed (selection, state);
+ else {
+ gtk_tree_selection_unselect_all (selection);
+ gtk_widget_set_sensitive (state->remove_group_button, FALSE);
+ }
+}
+
+static void
+dialog_kaplan_meier_tool_treeview_add_item (KaplanMeierToolState *state, guint i)
+{
+ GtkTreeIter iter;
+ char * name = g_strdup_printf (_("Group %d"), i);
+ GtkObject *adjustment_to = gtk_adjustment_new (0, 0, G_MAXUSHORT, 1, 1, 1);
+ GtkObject *adjustment_from = gtk_adjustment_new (0, 0, G_MAXUSHORT, 1, 1, 1);
+ gtk_list_store_append (state->groups_list, &iter);
+ gtk_list_store_set (state->groups_list, &iter,
+ GROUP_NAME, name,
+ GROUP_FROM, (uint) i,
+ GROUP_TO, (uint) i,
+ GROUP_ADJUSTMENT_FROM, adjustment_from,
+ GROUP_ADJUSTMENT_TO, adjustment_to,
+ -1);
+ g_free (name);
+}
+
+static void
+dialog_kaplan_meier_tool_setup_treeview (KaplanMeierToolState *state)
+{
+ guint i;
+ GtkCellRenderer *renderer;
+ GtkWidget *scrolled = glade_xml_get_widget (state->base.gui, "groups-scrolled");
+ GtkTreeSelection *selection;
+
+ state->groups_treeview = GTK_TREE_VIEW (glade_xml_get_widget
+ (state->base.gui,
+ "groups-tree"));
+ state->groups_list = gtk_list_store_new (GROUP_COLUMNS,
+ G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_OBJECT, G_TYPE_OBJECT);
+ state->groups_treeview = GTK_TREE_VIEW (gtk_tree_view_new_with_model
+ (GTK_TREE_MODEL (state->groups_list)));
+ selection = gtk_tree_view_get_selection (state->groups_treeview);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+
+ for (i = 0; i<2; i++)
+ dialog_kaplan_meier_tool_treeview_add_item (state, i);
+
+ g_signal_connect (selection,
+ "changed",
+ G_CALLBACK (cb_selection_changed), state);
+
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (G_OBJECT (renderer),
+ "editable", TRUE,
+ NULL);
+ gtk_tree_view_insert_column_with_attributes (state->groups_treeview,
+ -1, _("Group"),
+ renderer,
+ "text", GROUP_NAME,
+ NULL);
+ g_signal_connect (G_OBJECT (renderer), "edited",
+ G_CALLBACK (cb_group_name_edited), state);
+
+ renderer = gtk_cell_renderer_spin_new ();
+
+ g_object_set (G_OBJECT (renderer), "editable", TRUE, "xalign", 1.0,
+ "digits", 0, NULL);
+ g_signal_connect (G_OBJECT (renderer), "edited",
+ G_CALLBACK (cb_change_from), state);
+ gtk_tree_view_insert_column_with_attributes (state->groups_treeview,
+ -1, _("From"),
+ renderer,
+ "text", GROUP_FROM,
+ "adjustment", GROUP_ADJUSTMENT_FROM,
+ NULL);
+
+ renderer = gtk_cell_renderer_spin_new ();
+ g_object_set (G_OBJECT (renderer), "editable", TRUE, "xalign", 1.0,
+ "digits", 0, NULL);
+ g_signal_connect (G_OBJECT (renderer), "edited",
+ G_CALLBACK (cb_change_to), state);
+ gtk_tree_view_insert_column_with_attributes (state->groups_treeview,
+ -1, _("To"),
+ renderer,
+ "text", GROUP_TO,
+ "adjustment", GROUP_ADJUSTMENT_TO,
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (scrolled), GTK_WIDGET (state->groups_treeview));
+
+ cb_selection_changed (selection, state);
+}
+
+static gboolean
+kaplan_meier_tool_add_group_cb (G_GNUC_UNUSED GtkWidget *dummy,
+ KaplanMeierToolState *state)
+{
+ dialog_kaplan_meier_tool_treeview_add_item
+ (state, gtk_tree_model_iter_n_children (GTK_TREE_MODEL (state->groups_list),
+ NULL));
+ return FALSE;
+}
+
+static gboolean
+kaplan_meier_tool_remove_group_cb (G_GNUC_UNUSED GtkWidget *dummy,
+ KaplanMeierToolState *state)
+{
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+
+ selection = gtk_tree_view_get_selection (state->groups_treeview);
+
+ if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
+ gtk_list_store_remove ( state->groups_list, &iter);
+ }
+
+ return FALSE;
+}
+
+
/**
* dialog_kaplan_meier_tool:
* @wbcg:
@@ -270,6 +582,7 @@
dialog_kaplan_meier_tool (WBCGtk *wbcg, Sheet *sheet)
{
KaplanMeierToolState *state;
+ GtkWidget *widget;
if (wbcg == NULL) {
return 1;
@@ -311,9 +624,33 @@
state->tick_button = GTK_WIDGET (glade_xml_get_widget
(state->base.gui,
"tick-button"));
+ state->add_group_button = GTK_WIDGET (glade_xml_get_widget
+ (state->base.gui,
+ "add-button"));
+ state->remove_group_button = GTK_WIDGET (glade_xml_get_widget
+ (state->base.gui,
+ "remove-button"));
state->std_error_button = GTK_WIDGET (glade_xml_get_widget
(state->base.gui,
"std-error-button"));
+
+ state->groups_check = GTK_WIDGET (glade_xml_get_widget
+ (state->base.gui,
+ "groups-check"));
+ state->groups_table = GTK_WIDGET (glade_xml_get_widget
+ (state->base.gui,
+ "groups-table"));
+ state->groups_input = gnm_expr_entry_new (state->base.wbcg, TRUE);
+ gnm_expr_entry_set_flags (state->groups_input, GNM_EE_FORCE_ABS_REF,
+ GNM_EE_MASK);
+ gtk_table_attach (GTK_TABLE (state->groups_table), GTK_WIDGET (state->groups_input),
+ 1, 3, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+ dialog_kaplan_meier_tool_setup_treeview (state);
+
+ g_signal_connect_after (G_OBJECT (state->groups_check),
+ "toggled",
+ G_CALLBACK (kaplan_meier_tool_update_sensitivity_cb), state);
g_signal_connect_after (G_OBJECT (state->censorship_button),
"toggled",
G_CALLBACK (kaplan_meier_tool_update_sensitivity_cb), state);
@@ -323,9 +660,23 @@
g_signal_connect_after (G_OBJECT (state->std_error_button),
"toggled",
G_CALLBACK (kaplan_meier_tool_update_sensitivity_cb), state);
+ g_signal_connect_after (G_OBJECT (state->groups_input),
+ "changed",
+ G_CALLBACK (kaplan_meier_tool_update_sensitivity_cb),
+ state);
+
+ g_signal_connect_after (G_OBJECT (state->groups_check),
+ "toggled",
+ G_CALLBACK (kaplan_meier_tool_update_groups_sensitivity_cb), state);
g_signal_connect_after (G_OBJECT (state->tick_button),
"toggled",
G_CALLBACK (kaplan_meier_tool_set_graph_cb), state);
+ g_signal_connect_after (G_OBJECT (state->add_group_button),
+ "clicked",
+ G_CALLBACK (kaplan_meier_tool_add_group_cb), state);
+ g_signal_connect_after (G_OBJECT (state->remove_group_button),
+ "clicked",
+ G_CALLBACK (kaplan_meier_tool_remove_group_cb), state);
g_signal_connect_after (G_OBJECT (state->censor_spin_from),
"value-changed",
G_CALLBACK (kaplan_meier_tool_set_censor_from_cb), state);
@@ -335,12 +686,28 @@
g_signal_connect (G_OBJECT
(gnm_expr_entry_get_entry (
GNM_EXPR_ENTRY (state->base.input_entry_2))),
- "focus-in-event",
- G_CALLBACK (kaplan_meier_tool_set_censorship_cb), state);
+ "focus-in-event",
+ G_CALLBACK (kaplan_meier_tool_set_censorship_cb), state);
+ g_signal_connect (G_OBJECT
+ (gnm_expr_entry_get_entry (
+ GNM_EXPR_ENTRY (state->groups_input))),
+ "focus-in-event",
+ G_CALLBACK (kaplan_meier_tool_set_groups_cb), state);
+
+ gnumeric_editable_enters (GTK_WINDOW (state->base.dialog),
+ GTK_WIDGET (state->groups_input));
+
+ widget = glade_xml_get_widget (state->base.gui, "groups-label");
+ gtk_label_set_mnemonic_widget (GTK_LABEL (widget),
+ GTK_WIDGET (state->groups_input));
+ go_atk_setup_label (widget, GTK_WIDGET (state->groups_input));
gnm_dao_set_put (GNM_DAO (state->base.gdao), TRUE, TRUE);
kaplan_meier_tool_update_sensitivity_cb (NULL, state);
+ kaplan_meier_tool_update_groups_sensitivity_cb (NULL, state);
tool_load_selection ((GenericToolState *)state, TRUE);
+ gtk_widget_show_all (GTK_WIDGET (state->base.dialog));
+
return 0;
}
Modified: trunk/src/dialogs/dialog-analysis-tools.c
==============================================================================
--- trunk/src/dialogs/dialog-analysis-tools.c (original)
+++ trunk/src/dialogs/dialog-analysis-tools.c Fri Nov 14 07:36:31 2008
@@ -411,13 +411,21 @@
if (widget == NULL) {
state->input_entry = NULL;
} else {
- table = GTK_TABLE (glade_xml_get_widget (state->gui,
- "input-table"));
+ GList *this_label_widget;
+ GtkTableChild *tchild;
+
+ table = GTK_TABLE (gtk_widget_get_parent (widget));
state->input_entry = gnm_expr_entry_new (state->wbcg, TRUE);
gnm_expr_entry_set_flags (state->input_entry, flags | GNM_EE_FORCE_ABS_REF,
GNM_EE_MASK);
+
+ this_label_widget = g_list_find_custom
+ (table->children, widget, (GCompareFunc) dialog_tool_cmp);
+ tchild = (GtkTableChild *)(this_label_widget->data);
+
gtk_table_attach (table, GTK_WIDGET (state->input_entry),
- 1, 2, 0, 1,
+ tchild->right_attach, tchild->right_attach + 1,
+ tchild->top_attach, tchild->bottom_attach,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
g_signal_connect_after (G_OBJECT (state->input_entry),
@@ -452,9 +460,10 @@
tchild = (GtkTableChild *)(this_label_widget->data);
gtk_table_attach (table, GTK_WIDGET (state->input_entry_2),
- 1, 2, tchild->top_attach, tchild->bottom_attach,
- GTK_EXPAND | GTK_FILL, 0,
- 0, 0);
+ tchild->right_attach, tchild->right_attach + 1,
+ tchild->top_attach, tchild->bottom_attach,
+ GTK_EXPAND | GTK_FILL, 0,
+ 0, 0);
g_signal_connect_after (G_OBJECT (state->input_entry_2),
"changed",
G_CALLBACK (sensitivity_cb), state);
Modified: trunk/src/dialogs/kaplan-meier.glade
==============================================================================
--- trunk/src/dialogs/kaplan-meier.glade (original)
+++ trunk/src/dialogs/kaplan-meier.glade Fri Nov 14 07:36:31 2008
@@ -24,7 +24,7 @@
<property name="visible">True</property>
<property name="border_width">12</property>
<property name="n_rows">5</property>
- <property name="n_columns">2</property>
+ <property name="n_columns">3</property>
<property name="column_spacing">12</property>
<property name="row_spacing">2</property>
<child>
@@ -37,6 +37,12 @@
<placeholder/>
</child>
<child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
<widget class="GtkCheckButton" id="censor-button">
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -46,6 +52,7 @@
<property name="draw_indicator">True</property>
</widget>
<packing>
+ <property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
@@ -56,12 +63,13 @@
<widget class="GtkLabel" id="var2-label">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="xpad">25</property>
- <property name="label" translatable="yes">Censor column:</property>
+ <property name="label" translatable="yes">Censor co_lumn:</property>
<property name="use_underline">True</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
<packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
@@ -73,11 +81,12 @@
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="xpad">5</property>
- <property name="label" translatable="yes">Time column:</property>
+ <property name="label" translatable="yes">_Time column:</property>
<property name="use_underline">True</property>
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
<packing>
+ <property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
@@ -90,6 +99,8 @@
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
<packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
@@ -102,6 +113,8 @@
<property name="justify">GTK_JUSTIFY_RIGHT</property>
</widget>
<packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
@@ -114,8 +127,8 @@
<property name="climb_rate">1</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
@@ -128,8 +141,8 @@
<property name="climb_rate">1</property>
</widget>
<packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
@@ -154,6 +167,136 @@
</packing>
</child>
<child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">5</property>
+ <child>
+ <widget class="GtkCheckButton" id="groups-check">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Define _multiple groups</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="groups-table">
+ <property name="visible">True</property>
+ <property name="n_rows">7</property>
+ <property name="n_columns">3</property>
+ <property name="column_spacing">5</property>
+ <property name="row_spacing">5</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="groups-label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Groups column:</property>
+ </widget>
+ <packing>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="add-button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_SHRINK | GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="remove-button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-remove</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_SHRINK | GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="groups-scrolled">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">7</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Groups</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
<widget class="GtkVBox" id="vbox4">
<property name="visible">True</property>
<property name="border_width">12</property>
@@ -221,7 +364,7 @@
</child>
</widget>
<packing>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
@@ -234,7 +377,7 @@
</widget>
<packing>
<property name="type">tab</property>
- <property name="position">1</property>
+ <property name="position">2</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -246,7 +389,7 @@
</child>
</widget>
<packing>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
<child>
@@ -258,7 +401,7 @@
</widget>
<packing>
<property name="type">tab</property>
- <property name="position">2</property>
+ <property name="position">3</property>
<property name="tab_fill">False</property>
</packing>
</child>
Modified: trunk/src/tools/analysis-kaplan-meier.c
==============================================================================
--- trunk/src/tools/analysis-kaplan-meier.c (original)
+++ trunk/src/tools/analysis-kaplan-meier.c Fri Nov 14 07:36:31 2008
@@ -51,10 +51,15 @@
analysis_tools_data_kaplan_meier_t *info)
{
int rows, row;
- int std_err_col = info->censored ? 5 : 4;
- int prob_col = info->censored ? 4 : 3;
+ int std_err_col = info->censored ? 4 : 3;
+ int prob_col = info->censored ? 3 : 2;
+ int repetitions = ((info->group_list == NULL) ? 1
+ : g_slist_length (info->group_list));
+ int colspan = ((info->std_err ? 4 : 3) + (info->censored ? 1 : 0));
+ int i;
GnmExpr const *expr_data;
+ GnmExpr const *expr_group_data = NULL;
GnmExpr const *expr_small;
GnmExpr const *expr_time;
GnmExpr const *expr_at_risk;
@@ -70,6 +75,13 @@
GnmFunc *fd_sum;
GnmFunc *fd_sqrt = NULL;
+ GogGraph *graph;
+ GogPlot *plot;
+ SheetObject *so;
+ GOData *times;
+
+ GSList *gl = info->group_list;
+
fd_small = gnm_func_lookup ("SMALL", NULL);
gnm_func_ref (fd_small);
fd_if = gnm_func_lookup ("IF", NULL);
@@ -90,132 +102,32 @@
dao_set_italic (dao, 0, 0, 0, 0);
dao_set_cell (dao, 0, 0, _("Kaplan-Meier"));
- dao_set_italic (dao, 0, 1, prob_col, 1);
- if (info->censored)
- set_cell_text_row (dao, 0, 1,
- "/Time"
- "/At Risk"
- "/Deaths"
- "/Censures"
- "/Probability");
- else
- set_cell_text_row (dao, 0, 1,
- "/Time"
- "/At Risk"
- "/Deaths"
- "/Probability");
- if (info->std_err) {
- dao_set_italic (dao, std_err_col, 1, std_err_col, 1);
- dao_set_cell (dao, std_err_col, 1, "Standard Error");
+
+ if (info->chart) {
+ GogChart *chart;
+
+ graph = g_object_new (GOG_GRAPH_TYPE, NULL);
+ chart = GOG_CHART (gog_object_add_by_name (
+ GOG_OBJECT (graph), "Chart", NULL));
+
+ plot = gog_plot_new_by_name ("GogXYPlot");
+ go_object_set_property (G_OBJECT (plot), "interpolation",
+ "Default interpolation", "step-start",
+ NULL, NULL);
+
+ gog_object_add_by_name (GOG_OBJECT (chart),
+ "Plot", GOG_OBJECT (plot));
+ times = dao_go_data_vector (dao, 0, 2, 0, 1+rows);
}
- expr_data = gnm_expr_new_constant (value_dup (info->base.range_1));
-
- expr_at_risk = gnm_expr_new_funcall3
- (fd_if,
- gnm_expr_new_binary (make_cellref (-1, 0),
- GNM_EXPR_OP_EQUAL,
- gnm_expr_new_constant (value_new_string (""))),
- gnm_expr_new_constant (value_new_string ("")),
- gnm_expr_new_funcall1 (fd_sum,
- gnm_expr_new_funcall3
- (fd_if,
- gnm_expr_new_binary
- (gnm_expr_copy (expr_data),
- GNM_EXPR_OP_LT,
- make_cellref (-1, 0)),
- gnm_expr_new_constant (value_new_int (0)),
- gnm_expr_new_constant (value_new_int (1)))));
+ dao_set_italic (dao, 0, 1, 0, 1);
+ dao_set_cell (dao, 0, 1, _("Time"));
- if (info->censored) {
- GnmExpr const *expr_censor;
+ expr_data = gnm_expr_new_constant (value_dup (info->base.range_1));
- if (info->censor_mark == info->censor_mark_to)
- expr_censor = gnm_expr_new_funcall3
- (fd_if,
- gnm_expr_new_binary
- (gnm_expr_new_constant (value_dup (info->base.range_2)),
- GNM_EXPR_OP_EQUAL,
- gnm_expr_new_constant (value_new_int (info->censor_mark))),
- gnm_expr_new_constant (value_new_int (1)),
- gnm_expr_new_constant (value_new_int (0)));
- else
- expr_censor = gnm_expr_new_binary
- (gnm_expr_new_funcall3
- (fd_if,
- gnm_expr_new_binary
- (gnm_expr_new_constant (value_dup (info->base.range_2)),
- GNM_EXPR_OP_GTE,
- gnm_expr_new_constant (value_new_int (info->censor_mark))),
- gnm_expr_new_constant (value_new_int (1)),
- gnm_expr_new_constant (value_new_int (0))),
- GNM_EXPR_OP_MULT,
- gnm_expr_new_funcall3
- (fd_if,
- gnm_expr_new_binary
- (gnm_expr_new_constant (value_dup (info->base.range_2)),
- GNM_EXPR_OP_LTE,
- gnm_expr_new_constant (value_new_int (info->censor_mark_to))),
- gnm_expr_new_constant (value_new_int (1)),
- gnm_expr_new_constant (value_new_int (0))));
-
+ if (info->group_list != NULL && info->range_3 != NULL)
+ expr_group_data = gnm_expr_new_constant (value_dup (info->range_3));
- expr_deaths = gnm_expr_new_funcall3
- (fd_if,
- gnm_expr_new_binary (make_cellref (-1, 0),
- GNM_EXPR_OP_EQUAL,
- gnm_expr_new_constant (value_new_string (""))),
- gnm_expr_new_constant (value_new_string ("")),
- gnm_expr_new_funcall1 (fd_sum,
- gnm_expr_new_binary
- (gnm_expr_new_funcall3
- (fd_if,
- gnm_expr_new_binary
- (gnm_expr_copy (expr_data),
- GNM_EXPR_OP_EQUAL,
- make_cellref (-2, 0)),
- gnm_expr_new_constant (value_new_int (1)),
- gnm_expr_new_constant (value_new_int (0))),
- GNM_EXPR_OP_MULT,
- gnm_expr_new_binary
- (gnm_expr_new_constant (value_new_int (1)),
- GNM_EXPR_OP_SUB,
- gnm_expr_copy (expr_censor)))));
- expr_censures = gnm_expr_new_funcall3
- (fd_if,
- gnm_expr_new_binary (make_cellref (-1, 0),
- GNM_EXPR_OP_EQUAL,
- gnm_expr_new_constant (value_new_string (""))),
- gnm_expr_new_constant (value_new_string ("")),
- gnm_expr_new_funcall1 (fd_sum,
- gnm_expr_new_binary
- (gnm_expr_new_funcall3
- (fd_if,
- gnm_expr_new_binary
- (gnm_expr_copy (expr_data),
- GNM_EXPR_OP_EQUAL,
- make_cellref (-3, 0)),
- gnm_expr_new_constant (value_new_int (1)),
- gnm_expr_new_constant (value_new_int (0))),
- GNM_EXPR_OP_MULT,
- expr_censor)));
- } else
- expr_deaths = gnm_expr_new_funcall3
- (fd_if,
- gnm_expr_new_binary (make_cellref (-1, 0),
- GNM_EXPR_OP_EQUAL,
- gnm_expr_new_constant (value_new_string (""))),
- gnm_expr_new_constant (value_new_string ("")),
- gnm_expr_new_funcall1 (fd_sum,
- gnm_expr_new_funcall3
- (fd_if,
- gnm_expr_new_binary
- (gnm_expr_copy (expr_data),
- GNM_EXPR_OP_EQUAL,
- make_cellref (-2, 0)),
- gnm_expr_new_constant (value_new_int (1)),
- gnm_expr_new_constant (value_new_int (0)))));
-
expr_small = gnm_expr_new_funcall2 (fd_small,
gnm_expr_new_funcall3
(fd_if,
@@ -223,7 +135,7 @@
(gnm_expr_copy (expr_data),
GNM_EXPR_OP_GT,
make_cellref (0, -1)),
- expr_data,
+ gnm_expr_copy (expr_data),
gnm_expr_new_constant (value_new_string ("N/A"))),
gnm_expr_new_constant (value_new_int (1)));
expr_time = gnm_expr_new_funcall3 (fd_if,
@@ -231,165 +143,361 @@
gnm_expr_copy (expr_small)),
gnm_expr_new_constant (value_new_string ("")),
expr_small);
-
- expr_prob_zero = gnm_expr_new_binary (gnm_expr_new_binary (make_cellref (1 - prob_col, 0),
- GNM_EXPR_OP_SUB,
- make_cellref (2 - prob_col, 0)),
- GNM_EXPR_OP_DIV,
- make_cellref (1 - prob_col, 0));
- expr_prob = gnm_expr_new_funcall3 (fd_if,
- gnm_expr_new_binary
- (make_cellref (2 - prob_col, 0),
- GNM_EXPR_OP_EQUAL,
- gnm_expr_new_constant (value_new_string (""))),
- gnm_expr_new_constant (value_new_string ("")),
- gnm_expr_new_binary (gnm_expr_copy (expr_prob_zero),
- GNM_EXPR_OP_MULT,
- make_cellref (0, -1)));
-
- if (info->std_err) {
- expr_std_err = gnm_expr_new_funcall3 (fd_if,
- gnm_expr_new_binary
- (make_cellref (-1, 0),
- GNM_EXPR_OP_EQUAL,
- gnm_expr_new_constant (value_new_string (""))),
- gnm_expr_new_constant (value_new_string ("")),
- gnm_expr_new_binary (make_cellref (-1, 0),
- GNM_EXPR_OP_MULT,
- gnm_expr_new_funcall1
- (fd_sqrt,
- gnm_expr_new_binary
- (gnm_expr_new_binary
- (gnm_expr_new_constant
- (value_new_int (1)),
- GNM_EXPR_OP_SUB,
- make_cellref (-1, 0)),
- GNM_EXPR_OP_DIV,
- make_cellref
- (1 - std_err_col, 0)))));
-
- dao_set_format (dao, std_err_col, 2, std_err_col, rows + 1, "0.0000");
- dao_set_cell_expr (dao, std_err_col, 2, gnm_expr_copy (expr_std_err));
- }
-
- dao_set_format (dao, prob_col, 2, prob_col, rows + 1, "0.00%");
dao_set_cell_int (dao, 0, 2, 0);
- dao_set_cell_array_expr (dao, 1, 2, gnm_expr_copy (expr_at_risk));
- dao_set_cell_array_expr (dao, 2, 2, gnm_expr_copy (expr_deaths));
- dao_set_cell_expr (dao, prob_col, 2, expr_prob_zero);
-
- if (expr_censures != NULL)
- dao_set_cell_array_expr (dao, 3, 2, gnm_expr_copy (expr_censures));
-
- for (row = 1; row < rows; row++) {
- dao_set_cell_array_expr (dao, 0, 2+row, gnm_expr_copy (expr_time));
- dao_set_cell_array_expr (dao, 1, 2+row, gnm_expr_copy (expr_at_risk));
- dao_set_cell_array_expr (dao, 2, 2+row, gnm_expr_copy (expr_deaths));
- dao_set_cell_array_expr (dao, prob_col, 2+row, gnm_expr_copy (expr_prob));
- if (expr_censures != NULL)
- dao_set_cell_array_expr (dao, 3, 2+row, gnm_expr_copy (expr_censures));
- if (info->std_err)
- dao_set_cell_expr (dao, std_err_col, 2+row, gnm_expr_copy (expr_std_err));
- }
-
+ for (row = 1; row < rows; row++)
+ dao_set_cell_array_expr (dao, 0, 2+row, gnm_expr_copy (expr_time));
+
gnm_expr_free (expr_time);
- gnm_expr_free (expr_at_risk);
- gnm_expr_free (expr_deaths);
- gnm_expr_free (expr_prob);
- if (expr_censures != NULL)
- gnm_expr_free (expr_censures);
- if (expr_std_err != NULL)
- gnm_expr_free (expr_std_err);
+
- gnm_func_unref (fd_small);
- gnm_func_unref (fd_if);
- gnm_func_unref (fd_iserror);
- gnm_func_unref (fd_sum);
- if (fd_sqrt != NULL)
- gnm_func_unref (fd_sqrt);
- /* Create Chart if requested */
- if (info->chart) {
- SheetObject *so;
- GogGraph *graph;
- GogChart *chart;
- GogPlot *plot;
- GogSeries *series;
- GOData *times;
- GOData *probabilities;
- GogStyle *style;
+ dao->offset_col++;
+
+ /* Repeated Info start */
+ for (i = 0; i < repetitions; i++) {
+ GnmExpr const *expr_group = NULL;
- graph = g_object_new (GOG_GRAPH_TYPE, NULL);
- chart = GOG_CHART (gog_object_add_by_name (
- GOG_OBJECT (graph), "Chart", NULL));
+ if (gl != NULL && gl->data != NULL) {
+ analysis_tools_kaplan_meier_group_t *gd = gl->data;
+ if (gd->name != NULL) {
+ dao_set_italic (dao, 0, 0, 0, 0);
+ dao_set_cell (dao, 0, 0, gd->name);
- plot = gog_plot_new_by_name ("GogXYPlot");
- go_object_set_property (G_OBJECT (plot), "interpolation",
- "Default interpolation", "step-start",
- NULL, NULL);
+ if (gd->group_from == gd->group_to)
+ expr_group = gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_copy (expr_group_data),
+ GNM_EXPR_OP_EQUAL,
+ gnm_expr_new_constant (value_new_int (gd->group_from))),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (0)));
+ else
+ expr_group = gnm_expr_new_binary
+ (gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_copy (expr_group_data),
+ GNM_EXPR_OP_GTE,
+ gnm_expr_new_constant (value_new_int (gd->group_from))),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (0))),
+ GNM_EXPR_OP_MULT,
+ gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_copy (expr_group_data),
+ GNM_EXPR_OP_LTE,
+ gnm_expr_new_constant (value_new_int (gd->group_to))),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (0))));
+ }
+ }
- gog_object_add_by_name (GOG_OBJECT (chart),
- "Plot", GOG_OBJECT (plot));
+ if (expr_group == NULL)
+ expr_group = gnm_expr_new_constant (value_new_int (1));
- times = dao_go_data_vector (dao, 0, 2, 0, 1+rows);
- probabilities = dao_go_data_vector (dao, prob_col, 2, prob_col, 1+rows);
-
- if (info->censored && info->ticks)
- g_object_ref (times);
+ dao_set_italic (dao, 0, 1, prob_col, 1);
+ if (info->censored)
+ set_cell_text_row (dao, 0, 1,
+ _("/At Risk"
+ "/Deaths"
+ "/Censures"
+ "/Probability"));
+ else
+ set_cell_text_row (dao, 0, 1,
+ _("/At Risk"
+ "/Deaths"
+ "/Probability"));
+ if (info->std_err) {
+ dao_set_italic (dao, std_err_col, 1, std_err_col, 1);
+ dao_set_cell (dao, std_err_col, 1, _("Standard Error"));
+ }
+
+ expr_at_risk = gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary (make_cellref (-1-i*colspan, 0),
+ GNM_EXPR_OP_EQUAL,
+ gnm_expr_new_constant (value_new_string (""))),
+ gnm_expr_new_constant (value_new_string ("")),
+ gnm_expr_new_funcall1 (fd_sum,
+ gnm_expr_new_binary (
+ gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_copy (expr_data),
+ GNM_EXPR_OP_LT,
+ make_cellref (-1-i*colspan, 0)),
+ gnm_expr_new_constant (value_new_int (0)),
+ gnm_expr_new_constant (value_new_int (1))),
+ GNM_EXPR_OP_MULT,
+ gnm_expr_copy (expr_group))));
+
+ if (info->censored) {
+ GnmExpr const *expr_censor;
- series = gog_plot_new_series (plot);
- gog_series_set_dim (series, 0, times, NULL);
- gog_series_set_dim (series, 1, probabilities, NULL);
-
- style = gog_styled_object_get_style (GOG_STYLED_OBJECT (series));
- style->marker.auto_shape = FALSE;
- go_marker_set_shape (style->marker.mark, GO_MARKER_NONE);
- gog_styled_object_set_style (GOG_STYLED_OBJECT (series), style);
-
- if (info->censored && info->ticks) {
- GOData *censures;
- GnmExpr const *expr;
-
- expr = gnm_expr_new_binary
- (gnm_expr_new_binary (dao_get_rangeref (dao, prob_col, 2, prob_col, 1+rows),
+ if (info->censor_mark == info->censor_mark_to)
+ expr_censor = gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_new_constant (value_dup (info->base.range_2)),
+ GNM_EXPR_OP_EQUAL,
+ gnm_expr_new_constant (value_new_int (info->censor_mark))),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (0)));
+ else
+ expr_censor = gnm_expr_new_binary
+ (gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_new_constant (value_dup (info->base.range_2)),
+ GNM_EXPR_OP_GTE,
+ gnm_expr_new_constant (value_new_int (info->censor_mark))),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (0))),
+ GNM_EXPR_OP_MULT,
+ gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_new_constant (value_dup (info->base.range_2)),
+ GNM_EXPR_OP_LTE,
+ gnm_expr_new_constant (value_new_int (info->censor_mark_to))),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (0))));
+
+
+ expr_deaths = gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary (make_cellref (-1, 0),
+ GNM_EXPR_OP_EQUAL,
+ gnm_expr_new_constant (value_new_string (""))),
+ gnm_expr_new_constant (value_new_string ("")),
+ gnm_expr_new_funcall1 (fd_sum,
+ gnm_expr_new_binary
+ (gnm_expr_copy (expr_group),
+ GNM_EXPR_OP_MULT,
+ gnm_expr_new_binary
+ (gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_copy (expr_data),
+ GNM_EXPR_OP_EQUAL,
+ make_cellref (-2-i*colspan, 0)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (0))),
+ GNM_EXPR_OP_MULT,
+ gnm_expr_new_binary
+ (gnm_expr_new_constant (value_new_int (1)),
+ GNM_EXPR_OP_SUB,
+ gnm_expr_copy (expr_censor))))));
+ expr_censures = gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary (make_cellref (-1, 0),
+ GNM_EXPR_OP_EQUAL,
+ gnm_expr_new_constant (value_new_string (""))),
+ gnm_expr_new_constant (value_new_string ("")),
+ gnm_expr_new_funcall1 (fd_sum,
+ gnm_expr_new_binary
+ (gnm_expr_copy (expr_group),
+ GNM_EXPR_OP_MULT,
+ gnm_expr_new_binary
+ (gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_copy (expr_data),
+ GNM_EXPR_OP_EQUAL,
+ make_cellref (-3-i*colspan, 0)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (0))),
+ GNM_EXPR_OP_MULT,
+ expr_censor))));
+ } else
+ expr_deaths = gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary (make_cellref (-1, 0),
+ GNM_EXPR_OP_EQUAL,
+ gnm_expr_new_constant (value_new_string (""))),
+ gnm_expr_new_constant (value_new_string ("")),
+ gnm_expr_new_funcall1 (fd_sum,
+ gnm_expr_new_binary
+ (gnm_expr_copy (expr_group),
+ GNM_EXPR_OP_MULT,
+ gnm_expr_new_funcall3
+ (fd_if,
+ gnm_expr_new_binary
+ (gnm_expr_copy (expr_data),
+ GNM_EXPR_OP_EQUAL,
+ make_cellref (-2-i*colspan, 0)),
+ gnm_expr_new_constant (value_new_int (1)),
+ gnm_expr_new_constant (value_new_int (0))))));
+
+ expr_prob_zero = gnm_expr_new_binary (gnm_expr_new_binary (make_cellref ( - prob_col, 0),
+ GNM_EXPR_OP_SUB,
+ make_cellref (1 - prob_col, 0)),
GNM_EXPR_OP_DIV,
- dao_get_rangeref (dao, 3, 2, 3, 1+rows)),
- GNM_EXPR_OP_MULT,
- dao_get_rangeref (dao, 3, 2, 3, 1+rows));
+ make_cellref ( - prob_col, 0));
+ expr_prob = gnm_expr_new_funcall3 (fd_if,
+ gnm_expr_new_binary
+ (make_cellref (1 - prob_col, 0),
+ GNM_EXPR_OP_EQUAL,
+ gnm_expr_new_constant (value_new_string (""))),
+ gnm_expr_new_constant (value_new_string ("")),
+ gnm_expr_new_binary (gnm_expr_copy (expr_prob_zero),
+ GNM_EXPR_OP_MULT,
+ make_cellref (0, -1)));
+
+ if (info->std_err) {
+ expr_std_err = gnm_expr_new_funcall3 (fd_if,
+ gnm_expr_new_binary
+ (make_cellref (-1, 0),
+ GNM_EXPR_OP_EQUAL,
+ gnm_expr_new_constant (value_new_string (""))),
+ gnm_expr_new_constant (value_new_string ("")),
+ gnm_expr_new_binary (make_cellref (-1, 0),
+ GNM_EXPR_OP_MULT,
+ gnm_expr_new_funcall1
+ (fd_sqrt,
+ gnm_expr_new_binary
+ (gnm_expr_new_binary
+ (gnm_expr_new_constant
+ (value_new_int (1)),
+ GNM_EXPR_OP_SUB,
+ make_cellref (-1, 0)),
+ GNM_EXPR_OP_DIV,
+ make_cellref
+ ( - std_err_col, 0)))));
- censures = gnm_go_data_vector_new_expr (dao->sheet, gnm_expr_top_new (expr));
-
+ dao_set_format (dao, std_err_col, 2, std_err_col, rows + 1, "0.0000");
+ dao_set_cell_expr (dao, std_err_col, 2, gnm_expr_copy (expr_std_err));
+ }
+
+ dao_set_format (dao, prob_col, 2, prob_col, rows + 1, "0.00%");
+
+ dao_set_cell_array_expr (dao, 0, 2, gnm_expr_copy (expr_at_risk));
+ dao_set_cell_array_expr (dao, 1, 2, gnm_expr_copy (expr_deaths));
+ dao_set_cell_expr (dao, prob_col, 2, expr_prob_zero);
+
+ if (expr_censures != NULL)
+ dao_set_cell_array_expr (dao, 2, 2, gnm_expr_copy (expr_censures));
+
+ for (row = 1; row < rows; row++) {
+ dao_set_cell_array_expr (dao, 0, 2+row, gnm_expr_copy (expr_at_risk));
+ dao_set_cell_array_expr (dao, 1, 2+row, gnm_expr_copy (expr_deaths));
+ if (expr_censures != NULL)
+ dao_set_cell_array_expr (dao, 2, 2+row, gnm_expr_copy (expr_censures));
+ dao_set_cell_array_expr (dao, prob_col, 2+row, gnm_expr_copy (expr_prob));
+ if (info->std_err)
+ dao_set_cell_expr (dao, std_err_col, 2+row, gnm_expr_copy (expr_std_err));
+ }
+
+ gnm_expr_free (expr_at_risk);
+ gnm_expr_free (expr_deaths);
+ gnm_expr_free (expr_prob);
+ if (expr_censures != NULL) {
+ gnm_expr_free (expr_censures);
+ expr_censures = NULL;
+ }
+ if (expr_std_err != NULL) {
+ gnm_expr_free (expr_std_err);
+ expr_std_err = NULL;
+ }
+
+ /* Create Chart if requested */
+ if (info->chart) {
+ GogSeries *series;
+ GOData *probabilities;
+ GogStyle *style;
+
+ probabilities = dao_go_data_vector (dao, prob_col, 2, prob_col, 1+rows);
+
+ g_object_ref (times);
series = gog_plot_new_series (plot);
gog_series_set_dim (series, 0, times, NULL);
- gog_series_set_dim (series, 1, censures, NULL);
-
+ gog_series_set_dim (series, 1, probabilities, NULL);
+
style = gog_styled_object_get_style (GOG_STYLED_OBJECT (series));
style->marker.auto_shape = FALSE;
- go_marker_set_shape (style->marker.mark, GO_MARKER_TRIANGLE_DOWN);
- style->line.dash_type = GO_LINE_NONE;
- style->line.auto_dash = FALSE;
- style->line.width = 0;
+ go_marker_set_shape (style->marker.mark, GO_MARKER_NONE);
gog_styled_object_set_style (GOG_STYLED_OBJECT (series), style);
+
+ if (info->censored && info->ticks) {
+ GOData *censures;
+ GnmExpr const *expr;
+
+ expr = gnm_expr_new_binary
+ (gnm_expr_new_binary (dao_get_rangeref (dao, prob_col, 2, prob_col, 1+rows),
+ GNM_EXPR_OP_DIV,
+ dao_get_rangeref (dao, 2, 2, 2, 1+rows)),
+ GNM_EXPR_OP_MULT,
+ dao_get_rangeref (dao, 2, 2, 2, 1+rows));
+
+ censures = gnm_go_data_vector_new_expr (dao->sheet, gnm_expr_top_new (expr));
+
+ series = gog_plot_new_series (plot);
+ g_object_ref (times);
+ gog_series_set_dim (series, 0, times, NULL);
+ gog_series_set_dim (series, 1, censures, NULL);
+
+ style = gog_styled_object_get_style (GOG_STYLED_OBJECT (series));
+ style->marker.auto_shape = FALSE;
+ go_marker_set_shape (style->marker.mark, GO_MARKER_TRIANGLE_DOWN);
+ style->line.dash_type = GO_LINE_NONE;
+ style->line.auto_dash = FALSE;
+ style->line.width = 0;
+ gog_styled_object_set_style (GOG_STYLED_OBJECT (series), style);
+ }
}
+ gnm_expr_free (expr_group);
+
+ dao->offset_col += colspan;
+ if (gl != NULL)
+ gl = gl->next;
+ }
+ /* End of Loop */
+
+ if (info->chart) {
so = sheet_object_graph_new (graph);
g_object_unref (graph);
+ g_object_unref (times);
dao_set_sheet_object (dao, 0, 1, so);
- }
+ }
+
+ gnm_expr_free (expr_data);
+ if (expr_group_data != NULL)
+ gnm_expr_free (expr_group_data);
+
+ gnm_func_unref (fd_small);
+ gnm_func_unref (fd_if);
+ gnm_func_unref (fd_iserror);
+ gnm_func_unref (fd_sum);
+ if (fd_sqrt != NULL)
+ gnm_func_unref (fd_sqrt);
dao_redraw_respan (dao);
return FALSE;
}
+static void
+analysis_tool_kaplan_meier_clear_gl_cb (gpointer data, G_GNUC_UNUSED gpointer user_data)
+{
+ analysis_tools_kaplan_meier_group_t *group = data;
+
+ g_return_if_fail (data != NULL);
+
+ g_free (group->name);
+ g_free (group);
+}
gboolean
analysis_tool_kaplan_meier_engine (data_analysis_output_t *dao, gpointer specs,
analysis_tool_engine_t selector, gpointer result)
{
analysis_tools_data_kaplan_meier_t *info = specs;
+ int multiple;
switch (selector) {
case TOOL_ENGINE_UPDATE_DESCRIPTOR:
@@ -398,11 +506,17 @@
result)
== NULL);
case TOOL_ENGINE_UPDATE_DAO:
- dao_adjust (dao, (info->std_err ? 5 : 4) + (info->censored ? 1 : 0),
+ multiple = ((info->group_list == NULL) ? 1 : g_slist_length (info->group_list));
+ dao_adjust (dao, 1 + multiple * ((info->std_err ? 4 : 3) + (info->censored ? 1 : 0)),
info->base.range_1->v_range.cell.b.row
- info->base.range_1->v_range.cell.a.row + 3);
return FALSE;
case TOOL_ENGINE_CLEAN_UP:
+ value_release (info->range_3);
+ info->range_3 = NULL;
+ g_slist_foreach (info->group_list, analysis_tool_kaplan_meier_clear_gl_cb, NULL);
+ g_slist_free (info->group_list);
+ info->group_list = NULL;
return analysis_tool_generic_b_clean (specs);
case TOOL_ENGINE_LAST_VALIDITY_CHECK:
return FALSE;
Modified: trunk/src/tools/analysis-kaplan-meier.h
==============================================================================
--- trunk/src/tools/analysis-kaplan-meier.h (original)
+++ trunk/src/tools/analysis-kaplan-meier.h Fri Nov 14 07:36:31 2008
@@ -33,7 +33,6 @@
#include "tools.h"
#include "analysis-tools.h"
-
/* typedef struct { */
/* analysis_tools_error_code_t err; */
/* WorkbookControl *wbc; */
@@ -41,19 +40,27 @@
/* GnmValue *range_2; */
/* gboolean labels; */
/* gnm_float alpha; */
-/* } analysis_tools_data_ftest_t; */
-
+/* } analysis_tools_data_generic_b_t; */
typedef struct {
analysis_tools_data_generic_b_t base;
+ GnmValue *range_3;
gboolean censored;
int censor_mark;
int censor_mark_to;
gboolean chart;
gboolean ticks;
gboolean std_err;
+ GSList *group_list;
} analysis_tools_data_kaplan_meier_t;
+typedef struct {
+ char *name;
+ guint group_from;
+ guint group_to;
+} analysis_tools_kaplan_meier_group_t;
+
+
gboolean analysis_tool_kaplan_meier_engine (data_analysis_output_t *dao,
gpointer specs,
analysis_tool_engine_t selector,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]