Added a new top level menu to assist with the generation of graphics.
Currently it has only scatterplot, histogram and barchart.
* A Russian localisation has been contributed.
+ * The graphic user interface now has a Graphs menu to access the GRAPH
+ command.
+
+ * The GRAPH command now has a /BAR subcommand to draw barcharts.
+
* The graphical user interface uses Gtk+ version 3 instead of version 2.
Accordingly, it has a somewhat different look and feel.
@display
GRAPH
- /HISTOGRAM = @var{var}
- /SCATTERPLOT [(BIVARIATE)] = @var{var1} WITH @var{var2} [BY @var{var3}]
+ /HISTOGRAM [(NORMAL)]= @var{var}
+ /SCATTERPLOT [(BIVARIATE)] = @var{var1} WITH @var{var2} [BY @var{var3}]
+ /BAR = @{@var{summary-function}(@var{var1}) | @var{count-function}@} BY @var{var2} [BY @var{var3}]
[ /MISSING=@{LISTWISE, VARIABLE@} [@{EXCLUDE, INCLUDE@}] ]
[@{NOREPORT,REPORT@}]
The subcommand @subcmd{HISTOGRAM} produces a histogram. Only one variable is allowed for
the histogram plot.
+The keyword @subcmd{NORMAL} may be specified in parentheses, to indicate that the ideal normal curve
+should be superimposed over the histogram.
For an alternative method to produce histograms @pxref{EXAMINE}. The
following example produces a histogram plot for the variable @var{weight}.
/HISTOGRAM = @var{weight}.
@end example
+@cindex bar chart
+The subcommand @subcmd{BAR} produces a bar chart.
+This subcommand requires that a @var{count-function} be specified (with no arguments) or a @var{summary-function} with a variable @var{var1} in parentheses.
+Following the summary or count function, the keyword @subcmd{BY} should be specified and then a catagorical variable, @var{var2}.
+The values of the variable @var{var2} determine the labels of the bars to be plotted.
+Optionally a second categorical variable @var{var3} may be specified in which case a clustered (grouped) bar chart is produced.
+
+Valid count functions are
+@table @subcmd
+@item COUNT
+The weighted counts of the cases in each category.
+@item PCT
+The weighted counts of the cases in each category expressed as a percentage of the total weights of the cases.
+@item CUFREQ
+The cumulative weighted counts of the cases in each category.
+@item CUPCT
+The cumulative weighted counts of the cases in each category expressed as a percentage of the total weights of the cases.
+@end table
+
+The summary function is applied to @var{var1} across all cases in each category.
+The recognised summary functions are:
+@table @subcmd
+@item SUM
+The sum.
+@item MEAN
+The arithmetic mean.
+@item MAXIMUM
+The maximum value.
+@item MINIMUM
+The minimum value.
+@end table
+
+The following examples assume a dataset which is the results of a survey.
+Each respondent has indicated annual income, their sex and city of residence.
+One could create a bar chart showing how the mean income varies between of residents of different cities, thus:
+@example
+GRAPH /BAR = MEAN(@var{income}) BY @var{city}.
+@end example
+
+This can be extended to also indicate how income in each city differs between the sexes.
+@example
+GRAPH /BAR = MEAN(@var{income}) BY @var{city} BY @var{sex}.
+@end example
+
+One might also want to see how many respondents there are from each city. This can be achieved as follows:
+@example
+GRAPH /BAR = COUNT BY @var{city}.
+@end example
+
+Bar charts can also be produced using the @ref{FREQUENCIES} and @ref{CROSSTABS} commands.
+
@node CORRELATIONS
@section CORRELATIONS
src/language/stats/autorecode.c \
src/language/stats/binomial.c \
src/language/stats/binomial.h \
+ src/language/stats/chart-category.h \
src/language/stats/chisquare.c \
src/language/stats/chisquare.h \
src/language/stats/cochran.c \
--- /dev/null
+#ifndef BARCHART_DEF_H
+#define BARCHART_DEF_H 1
+
+struct ag_func
+{
+ const char *name;
+ const char *description;
+
+ int arity;
+ bool cumulative;
+ double (*pre) (void);
+ double (*calc) (double acc, double x, double w);
+ double (*post) (double acc, double cc);
+ double (*ppost) (double acc, double ccc);
+};
+
+extern const struct ag_func ag_func[];
+
+extern const int N_AG_FUNCS;
+
+#endif
#include <config.h>
#include <math.h>
+#include "gl/xalloc.h"
#include <gsl/gsl_cdf.h>
#include "libpspp/assertion.h"
#include "math/order-stats.h"
#include "output/charts/plot-hist.h"
#include "output/charts/scatterplot.h"
+#include "output/charts/barchart.h"
#include "language/command.h"
#include "language/lexer/lexer.h"
#include "language/lexer/value-parser.h"
#include "language/lexer/variable-parser.h"
+#include "language/stats/freq.h"
+#include "language/stats/chart-category.h"
#include "output/tab.h"
ST_XYZ
};
+enum bar_type
+ {
+ CBT_SIMPLE,
+ CBT_GROUPED,
+ CBT_STACKED,
+ CBT_RANGE
+ };
+
+
/* Variable index for histogram case */
enum
{
bool missing_pw;
/* ------------ Graph ---------------- */
+ bool normal; /* For histograms, draw the normal curve */
+
enum chart_type chart_type;
enum scatter_type scatter_type;
- const struct variable *byvar;
+ enum bar_type bar_type;
+ const struct variable *by_var[2];
+ size_t n_by_vars;
+
+ struct subcase ordering; /* Ordering for aggregation */
+ int agr; /* Index into ag_func */
+
/* A caseproto that contains the plot data */
struct caseproto *gr_proto;
};
+
+
+static double
+calc_mom1 (double acc, double x, double w)
+{
+ return acc + x * w;
+}
+
+static double
+calc_mom0 (double acc, double x UNUSED, double w)
+{
+ return acc + w;
+}
+
+static double
+pre_low_extreme (void)
+{
+ return -DBL_MAX;
+}
+
+static double
+calc_max (double acc, double x, double w UNUSED)
+{
+ return (acc > x) ? acc : x;
+}
+
+static double
+pre_high_extreme (void)
+{
+ return DBL_MAX;
+}
+
+static double
+calc_min (double acc, double x, double w UNUSED)
+{
+ return (acc < x) ? acc : x;
+}
+
+static double
+post_normalise (double acc, double cc)
+{
+ return acc / cc;
+}
+
+static double
+post_percentage (double acc, double ccc)
+{
+ return acc / ccc * 100.0;
+}
+
+
+const struct ag_func ag_func[] =
+ {
+ {"COUNT", N_("Count"), 0, 0, NULL, calc_mom0, 0, 0},
+ {"PCT", N_("Percentage"), 0, 0, NULL, calc_mom0, 0, post_percentage},
+ {"CUFREQ", N_("Cumulative Count"), 0, 1, NULL, calc_mom0, 0, 0},
+ {"CUPCT", N_("Cumulative Percent"), 0, 1, NULL, calc_mom0, 0, post_percentage},
+
+ {"MEAN", N_("Mean"), 1, 0, NULL, calc_mom1, post_normalise, 0},
+ {"SUM", N_("Sum"), 1, 0, NULL, calc_mom1, 0, 0},
+ {"MAXIMUM", N_("Maximum"), 1, 0, pre_low_extreme, calc_max, 0, 0},
+ {"MINIMUM", N_("Minimum"), 1, 0, pre_high_extreme, calc_min, 0, 0},
+ };
+
+const int N_AG_FUNCS = sizeof (ag_func) / sizeof (ag_func[0]);
+
+static bool
+parse_function (struct lexer *lexer, struct graph *graph)
+{
+ int i;
+ for (i = 0 ; i < N_AG_FUNCS; ++i)
+ {
+ if (lex_match_id (lexer, ag_func[i].name))
+ {
+ graph->agr = i;
+ break;
+ }
+ }
+ if (i == N_AG_FUNCS)
+ {
+ goto error;
+ }
+
+ graph->n_dep_vars = ag_func[i].arity;
+ if (ag_func[i].arity > 0)
+ {
+ int v;
+ if (!lex_force_match (lexer, T_LPAREN))
+ goto error;
+
+ graph->dep_vars = xzalloc (sizeof (graph->dep_vars) * graph->n_dep_vars);
+ for (v = 0; v < ag_func[i].arity; ++v)
+ {
+ graph->dep_vars[v] = parse_variable (lexer, graph->dict);
+ }
+
+ if (!lex_force_match (lexer, T_RPAREN))
+ goto error;
+ }
+
+ if (!lex_force_match (lexer, T_BY))
+ goto error;
+
+ graph->by_var[0] = parse_variable (lexer, graph->dict);
+ if (!graph->by_var[0])
+ {
+ goto error;
+ }
+ subcase_add_var (&graph->ordering, graph->by_var[0], SC_ASCEND);
+ graph->n_by_vars++;
+
+ if (lex_match (lexer, T_BY))
+ {
+ graph->by_var[1] = parse_variable (lexer, graph->dict);
+ if (!graph->by_var[1])
+ {
+ goto error;
+ }
+ subcase_add_var (&graph->ordering, graph->by_var[1], SC_ASCEND);
+ graph->n_by_vars++;
+ }
+
+ return true;
+
+ error:
+ lex_error (lexer, NULL);
+ return false;
+}
+
+
static void
show_scatterplot (const struct graph *cmd, struct casereader *input)
{
ds_init_empty (&title);
- if (cmd->byvar)
+ if (cmd->n_by_vars > 0)
{
ds_put_format (&title, _("%s vs. %s by %s"),
var_to_string (cmd->dep_vars[1]),
var_to_string (cmd->dep_vars[0]),
- var_to_string (cmd->byvar));
+ var_to_string (cmd->by_var[0]));
}
else
{
var_to_string (cmd->dep_vars[1]),
var_to_string (cmd->dep_vars[0]));
}
-
scatterplot = scatterplot_create (input,
var_to_string(cmd->dep_vars[0]),
var_to_string(cmd->dep_vars[1]),
- cmd->byvar,
+ (cmd->n_by_vars > 0) ? cmd->by_var[0] : NULL,
&byvar_overflow,
ds_cstr (&title),
cmd->es[0].minimum, cmd->es[0].maximum,
chart_item_submit
( histogram_chart_create (histogram->gsl_hist,
ds_cstr (&label), n, mean,
- sqrt (var), false));
+ sqrt (var), cmd->normal));
statistic_destroy (&histogram->parent);
ds_destroy (&label);
}
+static void
+run_barchart (struct graph *cmd, struct casereader *input)
+{
+ struct casegrouper *grouper;
+ struct casereader *group;
+ double ccc = 0.0;
+
+ if ( cmd->missing_pw == false)
+ input = casereader_create_filter_missing (input,
+ cmd->dep_vars,
+ cmd->n_dep_vars,
+ cmd->dep_excl,
+ NULL,
+ NULL);
+
+
+ input = sort_execute (input, &cmd->ordering);
+
+ struct freq **freqs = NULL;
+ int n_freqs = 0;
+
+ for (grouper = casegrouper_create_vars (input, cmd->by_var,
+ cmd->n_by_vars);
+ casegrouper_get_next_group (grouper, &group);
+ casereader_destroy (group))
+ {
+ int v;
+ struct ccase *c = casereader_peek (group, 0);
+
+ /* Deal with missing values in the categorical variables */
+ for (v = 0; v < cmd->n_by_vars; ++v)
+ {
+ if (var_is_value_missing (cmd->by_var[v], case_data (c, cmd->by_var[v]), cmd->fctr_excl) )
+ break;
+ }
+
+ if (v < cmd->n_by_vars)
+ {
+ case_unref (c);
+ continue;
+ }
+
+ freqs = xrealloc (freqs, sizeof (*freqs) * ++n_freqs);
+ freqs[n_freqs - 1] = xzalloc (sizeof (**freqs) +
+ sizeof (union value) * (cmd->n_by_vars - 1) );
+
+ if (ag_func[cmd->agr].cumulative && n_freqs >= 2)
+ freqs[n_freqs - 1]->count = freqs[n_freqs - 2]->count;
+ else
+ freqs[n_freqs - 1]->count = 0;
+ if (ag_func[cmd->agr].pre)
+ freqs[n_freqs - 1]->count = ag_func[cmd->agr].pre();
+
+
+ for (v = 0; v < cmd->n_by_vars; ++v)
+ {
+ value_clone (&freqs[n_freqs - 1]->values[v], case_data (c, cmd->by_var[v]),
+ var_get_width (cmd->by_var[v])
+ );
+ }
+ case_unref (c);
+
+ double cc = 0;
+ for (;(c = casereader_read (group)) != NULL; case_unref (c))
+ {
+ const double weight = dict_get_case_weight (cmd->dict,c,NULL);
+ const double x = (cmd->n_dep_vars > 0) ? case_data (c, cmd->dep_vars[0])->f : SYSMIS;
+
+ cc += weight;
+
+ freqs[n_freqs - 1]->count
+ = ag_func[cmd->agr].calc (freqs[n_freqs - 1]->count, x, weight);
+ }
+
+ if (ag_func[cmd->agr].post)
+ freqs[n_freqs - 1]->count
+ = ag_func[cmd->agr].post (freqs[n_freqs - 1]->count, cc);
+
+ ccc += cc;
+ }
+
+ casegrouper_destroy (grouper);
+
+ for (int i = 0; i < n_freqs; ++i)
+ {
+ if (ag_func[cmd->agr].ppost)
+ freqs[i]->count = ag_func[cmd->agr].ppost (freqs[i]->count, ccc);
+ }
+
+
+ {
+ struct string label;
+ ds_init_empty (&label);
+
+ if (cmd->n_dep_vars > 0)
+ ds_put_format (&label, _("%s of %s"),
+ ag_func[cmd->agr].description,
+ var_get_name (cmd->dep_vars[0]));
+ else
+ ds_put_cstr (&label,
+ ag_func[cmd->agr].description);
+
+ chart_item_submit (barchart_create (cmd->by_var, cmd->n_by_vars,
+ ds_cstr (&label),
+ freqs, n_freqs));
+
+ ds_destroy (&label);
+ }
+
+ for (int i = 0; i < n_freqs; ++i)
+ free (freqs[i]);
+
+ free (freqs);
+}
+
+
static void
run_graph (struct graph *cmd, struct casereader *input)
{
const double weight = dict_get_case_weight (cmd->dict,c,NULL);
if (cmd->chart_type == CT_HISTOGRAM)
case_data_rw_idx (outcase, HG_IDX_WT)->f = weight;
- if (cmd->chart_type == CT_SCATTERPLOT && cmd->byvar)
+ if (cmd->chart_type == CT_SCATTERPLOT && cmd->n_by_vars > 0)
value_copy (case_data_rw_idx (outcase, SP_IDX_BY),
- case_data (c, cmd->byvar),
- var_get_width (cmd->byvar));
+ case_data (c, cmd->by_var[0]),
+ var_get_width (cmd->by_var[0]));
for(int v=0;v<cmd->n_dep_vars;v++)
{
const struct variable *var = cmd->dep_vars[v];
graph.dict = dataset_dict (ds);
-
- /* ---------------- graph ------------------ */
graph.dep_vars = NULL;
graph.chart_type = CT_NONE;
graph.scatter_type = ST_BIVARIATE;
- graph.byvar = NULL;
+ graph.n_by_vars = 0;
graph.gr_proto = caseproto_create ();
+ subcase_init_empty (&graph.ordering);
+
while (lex_token (lexer) != T_ENDCMD)
{
lex_match (lexer, T_SLASH);
lex_error (lexer, _("Only one chart type is allowed."));
goto error;
}
+ graph.normal = false;
+ if (lex_match (lexer, T_LPAREN))
+ {
+ if (!lex_force_match_id (lexer, "NORMAL"))
+ goto error;
+
+ if (!lex_force_match (lexer, T_RPAREN))
+ goto error;
+
+ graph.normal = true;
+ }
if (!lex_force_match (lexer, T_EQUALS))
goto error;
graph.chart_type = CT_HISTOGRAM;
goto error;
}
}
+ else if (lex_match_id (lexer, "BAR"))
+ {
+ if (graph.chart_type != CT_NONE)
+ {
+ lex_error (lexer, _("Only one chart type is allowed."));
+ goto error;
+ }
+ graph.chart_type = CT_BAR;
+ graph.bar_type = CBT_SIMPLE;
+
+ if (lex_match (lexer, T_LPAREN))
+ {
+ if (lex_match_id (lexer, "SIMPLE"))
+ {
+ /* This is the default anyway */
+ }
+ else if (lex_match_id (lexer, "GROUPED"))
+ {
+ graph.bar_type = CBT_GROUPED;
+ goto error;
+ }
+ else if (lex_match_id (lexer, "STACKED"))
+ {
+ graph.bar_type = CBT_STACKED;
+ lex_error (lexer, _("%s is not yet implemented."), "STACKED");
+ goto error;
+ }
+ else if (lex_match_id (lexer, "RANGE"))
+ {
+ graph.bar_type = CBT_RANGE;
+ lex_error (lexer, _("%s is not yet implemented."), "RANGE");
+ goto error;
+ }
+ else
+ {
+ lex_error (lexer, NULL);
+ goto error;
+ }
+ if (!lex_force_match (lexer, T_RPAREN))
+ goto error;
+ }
+
+ if (!lex_force_match (lexer, T_EQUALS))
+ goto error;
+
+ if (! parse_function (lexer, &graph))
+ goto error;
+ }
else if (lex_match_id (lexer, "SCATTERPLOT"))
{
if (graph.chart_type != CT_NONE)
lex_error (lexer, _("Variable expected"));
goto error;
}
- graph.byvar = v;
+ graph.by_var[0] = v;
}
}
- else if (lex_match_id (lexer, "BAR"))
- {
- lex_error (lexer, _("%s is not yet implemented."),"BAR");
- goto error;
- }
else if (lex_match_id (lexer, "LINE"))
{
lex_error (lexer, _("%s is not yet implemented."),"LINE");
/* See scatterplot.h for the setup of the case prototype */
graph.gr_proto = caseproto_add_width (graph.gr_proto, 0); /* x value - SP_IDX_X*/
graph.gr_proto = caseproto_add_width (graph.gr_proto, 0); /* y value - SP_IDX_Y*/
- /* The byvar contains the plot categories for the different xy plot colors */
- if (graph.byvar) /* SP_IDX_BY */
- graph.gr_proto = caseproto_add_width (graph.gr_proto, var_get_width(graph.byvar));
+ /* The by_var contains the plot categories for the different xy plot colors */
+ if (graph.n_by_vars > 0) /* SP_IDX_BY */
+ graph.gr_proto = caseproto_add_width (graph.gr_proto, var_get_width(graph.by_var[0]));
break;
case CT_HISTOGRAM:
graph.gr_proto = caseproto_add_width (graph.gr_proto, 0); /* x value */
graph.gr_proto = caseproto_add_width (graph.gr_proto, 0); /* weight value */
break;
+ case CT_BAR:
+ break;
case CT_NONE:
- lex_error_expecting (lexer,"HISTOGRAM","SCATTERPLOT",NULL);
+ lex_error_expecting (lexer, "HISTOGRAM", "SCATTERPLOT", "BAR", NULL);
goto error;
default:
NOT_REACHED ();
grouper = casegrouper_create_splits (proc_open (ds), graph.dict);
while (casegrouper_get_next_group (grouper, &group))
- run_graph (&graph, group);
+ {
+ if (graph.chart_type == CT_BAR)
+ run_barchart (&graph, group);
+ else
+ run_graph (&graph, group);
+ }
ok = casegrouper_destroy (grouper);
ok = proc_commit (ds) && ok;
}
+ subcase_destroy (&graph.ordering);
free (graph.dep_vars);
pool_destroy (graph.pool);
caseproto_unref (graph.gr_proto);
return CMD_SUCCESS;
error:
+ subcase_destroy (&graph.ordering);
caseproto_unref (graph.gr_proto);
free (graph.dep_vars);
pool_destroy (graph.pool);
src/ui/gui/autorecode.ui \
src/ui/gui/binomial.ui \
src/ui/gui/compute.ui \
+ src/ui/gui/barchart.ui \
src/ui/gui/correlation.ui \
src/ui/gui/count.ui \
src/ui/gui/crosstabs.ui \
src/ui/gui/factor.ui \
src/ui/gui/find.ui \
src/ui/gui/frequencies.ui \
+ src/ui/gui/histogram.ui \
src/ui/gui/indep-samples.ui \
src/ui/gui/k-means.ui \
src/ui/gui/k-related.ui \
src/ui/gui/regression.ui \
src/ui/gui/reliability.ui \
src/ui/gui/roc.ui \
+ src/ui/gui/scatterplot.ui \
src/ui/gui/select-cases.ui \
src/ui/gui/t-test.ui \
src/ui/gui/text-data-import.ui \
src/ui/gui/psppire-dialog-action.h \
src/ui/gui/psppire-dialog-action-1sks.c \
src/ui/gui/psppire-dialog-action-1sks.h \
+ src/ui/gui/psppire-dialog-action-barchart.c \
+ src/ui/gui/psppire-dialog-action-barchart.h \
src/ui/gui/psppire-dialog-action-binomial.c \
src/ui/gui/psppire-dialog-action-binomial.h \
src/ui/gui/psppire-dialog-action-chisquare.c \
src/ui/gui/psppire-dialog-action-flip.h \
src/ui/gui/psppire-dialog-action-frequencies.c \
src/ui/gui/psppire-dialog-action-frequencies.h \
+ src/ui/gui/psppire-dialog-action-histogram.c \
+ src/ui/gui/psppire-dialog-action-histogram.h \
src/ui/gui/psppire-dialog-action-indep-samps.c \
src/ui/gui/psppire-dialog-action-indep-samps.h \
src/ui/gui/psppire-dialog-action-kmeans.c \
src/ui/gui/psppire-dialog-action-roc.h \
src/ui/gui/psppire-dialog-action-runs.c \
src/ui/gui/psppire-dialog-action-runs.h \
+ src/ui/gui/psppire-dialog-action-scatterplot.c \
+ src/ui/gui/psppire-dialog-action-scatterplot.h \
src/ui/gui/psppire-dialog-action-sort.c \
src/ui/gui/psppire-dialog-action-sort.h \
src/ui/gui/psppire-dialog-action-tt1s.c \
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface>
+ <requires lib="gtk+" version="3.0"/>
+ <requires lib="psppire" version="2054.17080"/>
+ <object class="PsppireDialog" id="barchart-dialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Barchart</property>
+ <property name="modal">True</property>
+ <property name="help_page">GRAPH</property>
+ <child>
+ <object class="GtkBox" id="dialog-hbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkGrid" id="table1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="PsppireSelector" id="indep-selector">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">False</property>
+ <property name="vexpand">False</property>
+ <property name="border_width">5</property>
+ <property name="primary">True</property>
+ <property name="source_widget">dict-view</property>
+ <property name="dest_widget">entry1</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="variables">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="shadow_type">etched-in</property>
+ <child>
+ <object class="PsppireDictView" id="dict-view">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">0</property>
+ <property name="headers_visible">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="psppire-dictview-selection1"/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="height">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkEntry" id="entry1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">•</property>
+ <property name="primary_icon_activatable">False</property>
+ <property name="secondary_icon_activatable">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Category A_xis:</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry1</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <object class="GtkGrid" id="table2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_right">5</property>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton-count">
+ <property name="label" translatable="yes">_N of cases</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton-cum-count">
+ <property name="label" translatable="yes">_Cum. n of cases</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton-count</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton3">
+ <property name="label" translatable="yes">Other _summary function</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="vexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton-count</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton-percent">
+ <property name="label" translatable="yes">% of c_ases</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton-count</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton-cum-percent">
+ <property name="label" translatable="yes">C_um. % of cases</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton-count</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkAspectFrame" id="aspectframe1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0.5</property>
+ <property name="shadow_type">none</property>
+ <property name="ratio">9.9999997473787516e-05</property>
+ <child>
+ <object class="PsppireSelector" id="psppire-selector1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="border_width">5</property>
+ <property name="source_widget">dict-view</property>
+ <property name="dest_widget">entry2</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkEntry" id="entry2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">•</property>
+ <property name="primary_icon_activatable">False</property>
+ <property name="secondary_icon_activatable">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">_Variable:</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry1</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="vexpand">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Bars Represent</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkEntry" id="entry3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">•</property>
+ <property name="primary_icon_activatable">False</property>
+ <property name="secondary_icon_activatable">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Category C_luster:</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry1</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="PsppireSelector" id="indep-selector1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">False</property>
+ <property name="vexpand">False</property>
+ <property name="border_width">5</property>
+ <property name="source_widget">dict-view</property>
+ <property name="dest_widget">entry3</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="PsppireVButtonBox" id="psppire-vbuttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">5</property>
+ <property name="orientation">vertical</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
<property name="stock-id">analyze-roc-curve</property>
</object>
</child>
+ <child>
+ <object class="GtkAction" id="graphs">
+ <property name="name">graphs</property>
+ <property name="label" translatable="yes">_Graphs</property>
+ </object>
+ </child>
+ <child>
+ <object class="PsppireDialogActionScatterplot" id="graphs_scatterplot">
+ <property name="manager">uimanager1</property>
+ <property name="name">graphs_scatterplot</property>
+ <property name="label" translatable="yes">_Scatterplot</property>
+ <property name="stock-id">graphs-scatterplot</property>
+ </object>
+ </child>
+ <child>
+ <object class="PsppireDialogActionHistogram" id="graphs_histogram">
+ <property name="manager">uimanager1</property>
+ <property name="name">graphs_histogram</property>
+ <property name="label" translatable="yes">_Histogram</property>
+ <property name="stock-id">graphs-histogram</property>
+ </object>
+ </child>
+ <child>
+ <object class="PsppireDialogActionBarchart" id="graphs_barchart">
+ <property name="manager">uimanager1</property>
+ <property name="name">graphs_barchart</property>
+ <property name="label" translatable="yes">_Barchart</property>
+ <property name="stock-id">graphs-barchart</property>
+ </object>
+ </child>
<child>
<object class="GtkAction" id="utilities">
<property name="name">utilities</property>
</menu>
<menuitem action="roc-curve"/>
</menu>
+ <menu action="graphs">
+ <menuitem action="graphs_scatterplot"/>
+ </menu>
+ <menu action="graphs">
+ <menuitem action="graphs_scatterplot"/>
+ <menuitem action="graphs_histogram"/>
+ <menuitem action="graphs_barchart"/>
+ </menu>
<menu action="utilities">
<menuitem action="utilities_variables"/>
<menuitem action="utilities_comments"/>
--- /dev/null
+<?xml version="1.0"?>
+<interface>
+ <requires lib="psppire" version="2054.17080"/>
+ <!-- interface-requires gtk+ 2.12 -->
+ <!-- interface-naming-policy project-wide -->
+ <object class="PsppireDialog" id="histogram-dialog">
+ <property name="title" translatable="yes">Histogram</property>
+ <property name="modal">True</property>
+ <property name="help-page">GRAPH</property>
+ <child>
+ <object class="GtkHBox" id="dialog-hbox1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">3</property>
+ <child>
+ <object class="PsppireSelector" id="indep-selector">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="no_show_all">True</property>
+ <property name="border_width">5</property>
+ <property name="source_widget">dict-view</property>
+ <property name="dest_widget">entry1</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="variables">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">etched-in</property>
+ <child>
+ <object class="PsppireDictView" id="dict-view">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="headers_visible">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkEntry" id="entry1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">•</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Variable:</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry1</property>
+ </object>
+ </child>
+ </object>
+ <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="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <object class="GtkAlignment" id="alignment3">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkVButtonBox" id="vbuttonbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkCheckButton" id="curve">
+ <property name="label" translatable="yes">_Display normal curve</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Display</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options">GTK_FILL</property>
+ <property name="x_padding">5</property>
+ <property name="y_padding">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="PsppireVButtonBox" id="psppire-vbuttonbox1">
+ <property name="visible">True</property>
+ <property name="border_width">5</property>
+ <property name="orientation">vertical</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
--- /dev/null
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2015 Free Software Foundation
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <config.h>
+
+#include "psppire-dialog-action-barchart.h"
+#include "psppire-value-entry.h"
+
+#include "dialog-common.h"
+#include <ui/syntax-gen.h>
+#include "psppire-var-view.h"
+
+#include "psppire-dialog.h"
+#include "builder-wrapper.h"
+
+#include "psppire-dict.h"
+#include "libpspp/str.h"
+
+#include "language/stats/chart-category.h"
+
+static void
+psppire_dialog_action_barchart_class_init (PsppireDialogActionBarchartClass *class);
+
+G_DEFINE_TYPE (PsppireDialogActionBarchart, psppire_dialog_action_barchart, PSPPIRE_TYPE_DIALOG_ACTION);
+
+static gboolean
+dialog_state_valid (gpointer rd_)
+{
+ PsppireDialogActionBarchart *rd = PSPPIRE_DIALOG_ACTION_BARCHART (rd_);
+
+ if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->button_summary_func)) )
+ {
+ if (0 == g_strcmp0 ("", gtk_entry_get_text (GTK_ENTRY (rd->var))))
+ return FALSE;
+ }
+
+ if (0 == g_strcmp0 ("", gtk_entry_get_text (GTK_ENTRY (rd->variable_xaxis))))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+refresh (PsppireDialogAction *rd_)
+{
+ PsppireDialogActionBarchart *rd = PSPPIRE_DIALOG_ACTION_BARCHART (rd_);
+
+ gtk_entry_set_text (GTK_ENTRY (rd->var), "");
+ gtk_entry_set_text (GTK_ENTRY (rd->variable_xaxis), "");
+ gtk_entry_set_text (GTK_ENTRY (rd->variable_cluster), "");
+
+ /* Set summary_func to true, then let it get unset again.
+ This ensures that the signal handler gets called. */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rd->button_summary_func), TRUE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rd->button_freq_func[0]), TRUE);
+
+ gtk_widget_set_sensitive (rd->combobox, FALSE);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (rd->combobox), 0);
+}
+
+static void
+on_summary_toggle (PsppireDialogActionBarchart *act)
+{
+ gboolean status = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (act->button_summary_func));
+
+ gtk_widget_set_sensitive (act->summary_variables, status);
+ gtk_widget_set_sensitive (act->combobox, status);
+}
+
+static void
+populate_combo_model (GtkComboBox *cb)
+{
+ int i;
+ GtkListStore *list = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
+ GtkTreeIter iter;
+ GtkCellRenderer *renderer ;
+
+ for (i = 0; i < N_AG_FUNCS; ++i)
+ {
+ const struct ag_func *af = ag_func + i;
+
+ if (af->arity == 0)
+ continue;
+
+ gtk_list_store_append (list, &iter);
+ gtk_list_store_set (list, &iter,
+ 0, af->description,
+ 1, af->name,
+ -1);
+ }
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cb), renderer, FALSE);
+
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (cb), renderer, "text", 0);
+
+ gtk_combo_box_set_model (GTK_COMBO_BOX (cb), GTK_TREE_MODEL (list));
+ g_object_unref (list);
+}
+
+
+static void
+psppire_dialog_action_barchart_activate (GtkAction *a)
+{
+ PsppireDialogActionBarchart *act = PSPPIRE_DIALOG_ACTION_BARCHART (a);
+ PsppireDialogAction *pda = PSPPIRE_DIALOG_ACTION (a);
+
+ GtkBuilder *xml = builder_new ("barchart.ui");
+ pda->dialog = get_widget_assert (xml, "barchart-dialog");
+ pda->source = get_widget_assert (xml, "dict-view");
+
+ act->variable_xaxis = get_widget_assert (xml, "entry1");
+ act->variable_cluster = get_widget_assert (xml, "entry3");
+ act->var = get_widget_assert (xml, "entry2");
+ act->button_freq_func[0] = get_widget_assert (xml, "radiobutton-count");
+ act->button_freq_func[1] = get_widget_assert (xml, "radiobutton-percent");
+ act->button_freq_func[2] = get_widget_assert (xml, "radiobutton-cum-count");
+ act->button_freq_func[3] = get_widget_assert (xml, "radiobutton-cum-percent");
+
+ act->button_summary_func = get_widget_assert (xml, "radiobutton3");
+ act->summary_variables = get_widget_assert (xml, "hbox1");
+ act->combobox = get_widget_assert (xml, "combobox1");
+
+ populate_combo_model (GTK_COMBO_BOX(act->combobox));
+
+ g_object_unref (xml);
+
+ g_signal_connect_swapped (act->button_summary_func, "toggled",
+ G_CALLBACK (on_summary_toggle), act);
+
+ psppire_dialog_action_set_refresh (pda, refresh);
+
+ psppire_dialog_action_set_valid_predicate (pda,
+ dialog_state_valid);
+
+ if (PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_barchart_parent_class)->activate)
+ PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_barchart_parent_class)->activate (pda);
+}
+
+static char *
+generate_syntax (PsppireDialogAction *a)
+{
+ PsppireDialogActionBarchart *rd = PSPPIRE_DIALOG_ACTION_BARCHART (a);
+ gchar *text;
+ const gchar *var_name_xaxis = gtk_entry_get_text (GTK_ENTRY (rd->variable_xaxis));
+ const gchar *var_name_cluster = gtk_entry_get_text (GTK_ENTRY (rd->variable_cluster));
+
+ GString *string = g_string_new ("GRAPH /BAR = ");
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->button_summary_func)))
+ {
+ GtkTreeIter iter;
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (rd->combobox), &iter))
+ {
+ GValue value = {0};
+ GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (rd->combobox));
+ gtk_tree_model_get_value (model, &iter, 1, &value);
+ g_string_append (string, g_value_get_string (&value));
+ g_value_unset (&value);
+ }
+ g_string_append (string, " (");
+ g_string_append (string, gtk_entry_get_text (GTK_ENTRY (rd->var)));
+ g_string_append (string, ")");
+ }
+ else
+ {
+ int b;
+ for (b = 0; b < 4; ++b)
+ {
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->button_freq_func[b])))
+ break;
+ }
+ switch (b)
+ {
+ case 0:
+ g_string_append (string, "COUNT");
+ break;
+ case 1:
+ g_string_append (string, "PCT");
+ break;
+ case 2:
+ g_string_append (string, "CUFREQ");
+ break;
+ case 3:
+ g_string_append (string, "CUPCT");
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+
+ g_string_append (string, " BY ");
+ g_string_append (string, var_name_xaxis);
+
+ if (g_strcmp0 (var_name_cluster, ""))
+ {
+ g_string_append (string, " BY ");
+ g_string_append (string, var_name_cluster);
+ }
+
+ g_string_append (string, ".\n");
+
+ text = string->str;
+
+ g_string_free (string, FALSE);
+
+ return text;
+}
+
+static void
+psppire_dialog_action_barchart_class_init (PsppireDialogActionBarchartClass *class)
+{
+ psppire_dialog_action_set_activation (class, psppire_dialog_action_barchart_activate);
+
+ PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax = generate_syntax;
+}
+
+
+static void
+psppire_dialog_action_barchart_init (PsppireDialogActionBarchart *act)
+{
+}
--- /dev/null
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2015 Free Software Foundation
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include "psppire-dialog-action.h"
+
+#ifndef __PSPPIRE_DIALOG_ACTION_BARCHART_H__
+#define __PSPPIRE_DIALOG_ACTION_BARCHART_H__
+
+G_BEGIN_DECLS
+
+
+#define PSPPIRE_TYPE_DIALOG_ACTION_BARCHART (psppire_dialog_action_barchart_get_type ())
+
+#define PSPPIRE_DIALOG_ACTION_BARCHART(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ PSPPIRE_TYPE_DIALOG_ACTION_BARCHART, PsppireDialogActionBarchart))
+
+#define PSPPIRE_DIALOG_ACTION_BARCHART_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ PSPPIRE_TYPE_DIALOG_ACTION_BARCHART, \
+ PsppireDialogActionBarchartClass))
+
+
+#define PSPPIRE_IS_DIALOG_ACTION_BARCHART(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_DIALOG_ACTION_BARCHART))
+
+#define PSPPIRE_IS_DIALOG_ACTION_BARCHART_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_TYPE_DIALOG_ACTION_BARCHART))
+
+
+#define PSPPIRE_DIALOG_ACTION_BARCHART_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ PSPPIRE_TYPE_DIALOG_ACTION_BARCHART, \
+ PsppireDialogActionBarchartClass))
+
+typedef struct _PsppireDialogActionBarchart PsppireDialogActionBarchart;
+typedef struct _PsppireDialogActionBarchartClass PsppireDialogActionBarchartClass;
+
+
+struct _PsppireDialogActionBarchart
+{
+ PsppireDialogAction parent;
+
+ /*< private >*/
+
+ GtkWidget *variable_xaxis;
+ GtkWidget *variable_cluster;
+ GtkWidget *var;
+ GtkWidget *button_freq_func[4];
+ GtkWidget *button_summary_func;
+ GtkWidget *summary_variables;
+ GtkWidget *combobox;
+};
+
+
+struct _PsppireDialogActionBarchartClass
+{
+ PsppireDialogActionClass parent_class;
+};
+
+
+GType psppire_dialog_action_barchart_get_type (void) ;
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_DIALOG_ACTION_BARCHART_H__ */
--- /dev/null
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2015 Free Software Foundation
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <config.h>
+
+#include "psppire-dialog-action-histogram.h"
+#include "psppire-value-entry.h"
+
+#include "dialog-common.h"
+#include <ui/syntax-gen.h>
+#include "psppire-var-view.h"
+
+#include "psppire-dialog.h"
+#include "builder-wrapper.h"
+
+#include "psppire-dict.h"
+#include "libpspp/str.h"
+
+static void
+psppire_dialog_action_histogram_class_init (PsppireDialogActionHistogramClass *class);
+
+G_DEFINE_TYPE (PsppireDialogActionHistogram, psppire_dialog_action_histogram, PSPPIRE_TYPE_DIALOG_ACTION);
+
+static gboolean
+dialog_state_valid (gpointer data)
+{
+ PsppireDialogActionHistogram *rd = data;
+
+ const gchar *var_name = gtk_entry_get_text (GTK_ENTRY (rd->variable));
+ const struct variable *var = psppire_dict_lookup_var (PSPPIRE_DIALOG_ACTION (rd)->dict, var_name);
+
+ if ( var == NULL)
+ return FALSE;
+
+
+ return TRUE;
+}
+
+static void
+refresh (PsppireDialogAction *rd_)
+{
+ PsppireDialogActionHistogram *rd = PSPPIRE_DIALOG_ACTION_HISTOGRAM (rd_);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rd->curve), FALSE);
+ gtk_entry_set_text (GTK_ENTRY (rd->variable), "");
+}
+
+static void
+psppire_dialog_action_histogram_activate (GtkAction *a)
+{
+ PsppireDialogActionHistogram *act = PSPPIRE_DIALOG_ACTION_HISTOGRAM (a);
+ PsppireDialogAction *pda = PSPPIRE_DIALOG_ACTION (a);
+
+ GtkBuilder *xml = builder_new ("histogram.ui");
+ pda->dialog = get_widget_assert (xml, "histogram-dialog");
+ pda->source = get_widget_assert (xml, "dict-view");
+
+ act->variable = get_widget_assert (xml, "entry1");
+ act->curve = get_widget_assert (xml, "curve");
+
+ g_object_unref (xml);
+
+ psppire_dialog_action_set_refresh (pda, refresh);
+
+ psppire_dialog_action_set_valid_predicate (pda,
+ dialog_state_valid);
+
+ if (PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_histogram_parent_class)->activate)
+ PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_histogram_parent_class)->activate (pda);
+}
+
+
+
+static char *
+generate_syntax (PsppireDialogAction *a)
+{
+ PsppireDialogActionHistogram *rd = PSPPIRE_DIALOG_ACTION_HISTOGRAM (a);
+ gchar *text;
+ const gchar *var_name = gtk_entry_get_text (GTK_ENTRY (rd->variable));
+ GString *string = g_string_new ("GRAPH /HISTOGRAM ");
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->curve)))
+ {
+ g_string_append (string, "(NORMAL)");
+ }
+
+ g_string_append (string, " = ");
+ g_string_append (string, var_name);
+
+ g_string_append (string, ".\n");
+
+ text = string->str;
+
+ g_string_free (string, FALSE);
+
+ return text;
+}
+
+static void
+psppire_dialog_action_histogram_class_init (PsppireDialogActionHistogramClass *class)
+{
+ GtkActionClass *action_class = GTK_ACTION_CLASS (class);
+
+ action_class->activate = psppire_dialog_action_histogram_activate;
+
+ PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax = generate_syntax;
+}
+
+
+static void
+psppire_dialog_action_histogram_init (PsppireDialogActionHistogram *act)
+{
+}
+
--- /dev/null
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2015 Free Software Foundation
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include "psppire-dialog-action.h"
+
+#ifndef __PSPPIRE_DIALOG_ACTION_HISTOGRAM_H__
+#define __PSPPIRE_DIALOG_ACTION_HISTOGRAM_H__
+
+G_BEGIN_DECLS
+
+
+#define PSPPIRE_TYPE_DIALOG_ACTION_HISTOGRAM (psppire_dialog_action_histogram_get_type ())
+
+#define PSPPIRE_DIALOG_ACTION_HISTOGRAM(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ PSPPIRE_TYPE_DIALOG_ACTION_HISTOGRAM, PsppireDialogActionHistogram))
+
+#define PSPPIRE_DIALOG_ACTION_HISTOGRAM_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ PSPPIRE_TYPE_DIALOG_ACTION_HISTOGRAM, \
+ PsppireDialogActionHistogramClass))
+
+
+#define PSPPIRE_IS_DIALOG_ACTION_HISTOGRAM(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_DIALOG_ACTION_HISTOGRAM))
+
+#define PSPPIRE_IS_DIALOG_ACTION_HISTOGRAM_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_TYPE_DIALOG_ACTION_HISTOGRAM))
+
+
+#define PSPPIRE_DIALOG_ACTION_HISTOGRAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ PSPPIRE_TYPE_DIALOG_ACTION_HISTOGRAM, \
+ PsppireDialogActionHistogramClass))
+
+typedef struct _PsppireDialogActionHistogram PsppireDialogActionHistogram;
+typedef struct _PsppireDialogActionHistogramClass PsppireDialogActionHistogramClass;
+
+
+struct _PsppireDialogActionHistogram
+{
+ PsppireDialogAction parent;
+
+ /*< private >*/
+ gboolean dispose_has_run ;
+
+ GtkWidget *variable;
+ GtkWidget *curve;
+};
+
+
+struct _PsppireDialogActionHistogramClass
+{
+ PsppireDialogActionClass parent_class;
+};
+
+
+GType psppire_dialog_action_histogram_get_type (void) ;
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_DIALOG_ACTION_HISTOGRAM_H__ */
--- /dev/null
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2015 Free Software Foundation
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <config.h>
+
+#include "psppire-dialog-action-scatterplot.h"
+
+#include "psppire-var-view.h"
+
+#include "psppire-dialog.h"
+#include "builder-wrapper.h"
+#include "helper.h"
+
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+
+static void psppire_dialog_action_scatterplot_init (PsppireDialogActionScatterplot *act);
+static void psppire_dialog_action_scatterplot_class_init (PsppireDialogActionScatterplotClass *class);
+
+G_DEFINE_TYPE (PsppireDialogActionScatterplot, psppire_dialog_action_scatterplot, PSPPIRE_TYPE_DIALOG_ACTION);
+
+
+static char *
+generate_syntax (PsppireDialogAction *act)
+{
+ PsppireDialogActionScatterplot *ow = PSPPIRE_DIALOG_ACTION_SCATTERPLOT (act);
+ gchar *text;
+ struct string dss;
+
+ ds_init_cstr (&dss, "GRAPH SCATTERPLOT(BIVARIATE) = ");
+
+ ds_put_cstr (&dss, gtk_entry_get_text (GTK_ENTRY (ow->y_axis)));
+
+ ds_put_cstr (&dss, " WITH ");
+
+ ds_put_cstr (&dss, gtk_entry_get_text (GTK_ENTRY (ow->x_axis)));
+
+ ds_put_cstr (&dss, ".\n");
+
+ text = ds_steal_cstr (&dss);
+ ds_destroy (&dss);
+
+ return text;
+}
+
+
+static gboolean
+dialog_state_valid (gpointer data)
+{
+ PsppireDialogActionScatterplot *ow = PSPPIRE_DIALOG_ACTION_SCATTERPLOT (data);
+
+ const char *xvar = gtk_entry_get_text (GTK_ENTRY (ow->x_axis));
+ const char *yvar = gtk_entry_get_text (GTK_ENTRY (ow->y_axis));
+
+ if ( 0 == strcmp ("", xvar))
+ return FALSE;
+
+ if ( 0 == strcmp ("", yvar))
+ return FALSE;
+
+
+ return TRUE;
+}
+
+static void
+refresh (PsppireDialogAction *rd_)
+{
+ PsppireDialogActionScatterplot *ow = PSPPIRE_DIALOG_ACTION_SCATTERPLOT (rd_);
+
+ gtk_entry_set_text (GTK_ENTRY (ow->x_axis), "");
+ gtk_entry_set_text (GTK_ENTRY (ow->y_axis), "");
+}
+
+
+
+static void
+psppire_dialog_action_scatterplot_activate (GtkAction *a)
+{
+ PsppireDialogAction *pda = PSPPIRE_DIALOG_ACTION (a);
+ PsppireDialogActionScatterplot *act = PSPPIRE_DIALOG_ACTION_SCATTERPLOT (a);
+
+ GtkBuilder *xml = builder_new ("scatterplot.ui");
+
+ pda->dialog = get_widget_assert (xml, "scatterplot-dialog");
+ pda->source = get_widget_assert (xml, "scatterplot-treeview1");
+
+ act->y_axis = get_widget_assert (xml, "scatterplot-y-axis");
+ act->x_axis = get_widget_assert (xml, "scatterplot-x-axis");
+
+ psppire_dialog_action_set_valid_predicate (pda, dialog_state_valid);
+ psppire_dialog_action_set_refresh (pda, refresh);
+
+ g_object_unref (xml);
+
+ if (PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_scatterplot_parent_class)->activate)
+ PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_scatterplot_parent_class)->activate (pda);
+}
+
+static void
+psppire_dialog_action_scatterplot_class_init (PsppireDialogActionScatterplotClass *class)
+{
+ GtkActionClass *action_class = GTK_ACTION_CLASS (class);
+
+ action_class->activate = psppire_dialog_action_scatterplot_activate;
+ PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax = generate_syntax;
+}
+
+
+static void
+psppire_dialog_action_scatterplot_init (PsppireDialogActionScatterplot *act)
+{
+}
--- /dev/null
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2015 Free Software Foundation
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include "psppire-dialog-action.h"
+
+#ifndef __PSPPIRE_DIALOG_ACTION_SCATTERPLOT_H__
+#define __PSPPIRE_DIALOG_ACTION_SCATTERPLOT_H__
+
+G_BEGIN_DECLS
+
+
+#define PSPPIRE_TYPE_DIALOG_ACTION_SCATTERPLOT (psppire_dialog_action_scatterplot_get_type ())
+
+#define PSPPIRE_DIALOG_ACTION_SCATTERPLOT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ PSPPIRE_TYPE_DIALOG_ACTION_SCATTERPLOT, PsppireDialogActionScatterplot))
+
+#define PSPPIRE_DIALOG_ACTION_SCATTERPLOT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ PSPPIRE_TYPE_DIALOG_ACTION_SCATTERPLOT, \
+ PsppireDialogActionScatterplotClass))
+
+
+#define PSPPIRE_IS_DIALOG_ACTION_SCATTERPLOT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_DIALOG_ACTION_SCATTERPLOT))
+
+#define PSPPIRE_IS_DIALOG_ACTION_SCATTERPLOT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_TYPE_DIALOG_ACTION_SCATTERPLOT))
+
+
+#define PSPPIRE_DIALOG_ACTION_SCATTERPLOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ PSPPIRE_TYPE_DIALOG_ACTION_SCATTERPLOT, \
+ PsppireDialogActionScatterplotClass))
+
+typedef struct _PsppireDialogActionScatterplot PsppireDialogActionScatterplot;
+typedef struct _PsppireDialogActionScatterplotClass PsppireDialogActionScatterplotClass;
+
+
+struct _PsppireDialogActionScatterplot
+{
+ PsppireDialogAction parent;
+
+ /*< private >*/
+ gboolean dispose_has_run ;
+
+ GtkWidget *x_axis;
+ GtkWidget *y_axis;
+};
+
+
+struct _PsppireDialogActionScatterplotClass
+{
+ PsppireDialogActionClass parent_class;
+};
+
+
+GType psppire_dialog_action_scatterplot_get_type (void) ;
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_DIALOG_ACTION_SCATTERPLOT_H__ */
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="psppire" version="2054.17080"/>
+ <!-- interface-requires gtk+ 2.12 -->
+ <!-- interface-naming-policy project-wide -->
+ <object class="PsppireDialog" id="scatterplot-dialog">
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="title" translatable="yes">Scatterplot</property>
+ <property name="modal">True</property>
+ <property name="help_page">GRAPH</property>
+ <child>
+ <object class="GtkHBox" id="dialog-hbox15">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="top_padding">5</property>
+ <property name="bottom_padding">5</property>
+ <property name="left_padding">5</property>
+ <child>
+ <object class="GtkTable" id="table4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">3</property>
+ <property name="column_spacing">5</property>
+ <child>
+ <object class="GtkVBox" id="vbox-x">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <object class="GtkLabel" id="label-x-axis">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_X Axis:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">scatterplot-x-axis</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="scatterplot-x-axis">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="invisible_char">●</property>
+ <property name="primary_icon_activatable">False</property>
+ <property name="secondary_icon_activatable">False</property>
+ <property name="primary_icon_sensitive">True</property>
+ <property name="secondary_icon_sensitive">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <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="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox-y">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <object class="GtkLabel" id="label-y-axis">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Y Axis:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">scatterplot-y-axis</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="scatterplot-y-axis">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="invisible_char">●</property>
+ <property name="primary_icon_activatable">False</property>
+ <property name="secondary_icon_activatable">False</property>
+ <property name="primary_icon_sensitive">True</property>
+ <property name="secondary_icon_sensitive">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="y_options">GTK_EXPAND</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">etched-in</property>
+ <child>
+ <object class="PsppireDictView" id="scatterplot-treeview1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <object class="PsppireSelector" id="scatterplot-selector-x">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">5</property>
+ <property name="source_widget">scatterplot-treeview1</property>
+ <property name="dest_widget">scatterplot-x-axis</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <object class="PsppireSelector" id="scatterplot-selector-y">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">5</property>
+ <property name="source_widget">scatterplot-treeview1</property>
+ <property name="dest_widget">scatterplot-y-axis</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="PsppireVButtonBox" id="psppire-vbuttonbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">5</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
#include "psppire-val-chooser.h"
#include "psppire-checkbox-treeview.h"
+#include "psppire-dialog-action-barchart.h"
#include "psppire-dialog-action-binomial.h"
#include "psppire-dialog-action-chisquare.h"
#include "psppire-dialog-action-compute.h"
#include "psppire-dialog-action-flip.h"
#include "psppire-dialog-action-factor.h"
#include "psppire-dialog-action-frequencies.h"
+#include "psppire-dialog-action-histogram.h"
#include "psppire-dialog-action-indep-samps.h"
#include "psppire-dialog-action-k-related.h"
#include "psppire-dialog-action-1sks.h"
#include "psppire-dialog-action-reliability.h"
#include "psppire-dialog-action-roc.h"
#include "psppire-dialog-action-runs.h"
+#include "psppire-dialog-action-scatterplot.h"
#include "psppire-dialog-action-sort.h"
#include "psppire-dialog-action-tt1s.h"
#include "psppire-dialog-action-two-sample.h"
psppire_dialog_action_1sks_get_type ();
psppire_dialog_action_binomial_get_type ();
+ psppire_dialog_action_barchart_get_type ();
psppire_dialog_action_chisquare_get_type ();
psppire_dialog_action_compute_get_type ();
psppire_dialog_action_correlation_get_type ();
psppire_dialog_action_factor_get_type ();
psppire_dialog_action_flip_get_type ();
psppire_dialog_action_frequencies_get_type ();
+ psppire_dialog_action_histogram_get_type ();
psppire_dialog_action_logistic_get_type ();
psppire_dialog_action_kmeans_get_type ();
psppire_dialog_action_k_related_get_type ();
psppire_dialog_action_regression_get_type ();
psppire_dialog_action_roc_get_type ();
psppire_dialog_action_runs_get_type ();
+ psppire_dialog_action_scatterplot_get_type ();
psppire_dialog_action_sort_get_type ();
psppire_dialog_action_tt1s_get_type ();
psppire_dialog_action_two_sample_get_type ();
GLM c BY b.
GRAPH /HISTOGRAM = b .
GRAPH /SCATTERPLOT(BIVARIATE) = b with c by e .
+GRAPH /BAR (GROUPED) = MEAN(b) by c by e.
+GRAPH /BAR = COUNT BY b.
LIST.
LOGISTIC REGRESSION q WITH b.
MEANS c b.
AT_CHECK([pspp -o pspp.pdf null-hist.sps], [0], [ignore])
dnl Ignore output -- this is just a no-crash check.
AT_CLEANUP
+
+
+
+
+AT_SETUP([GRAPH barcharts])
+AT_CHECK([ln -s $top_srcdir/examples/physiology.sav .], [0])
+AT_CHECK([ln -s $top_srcdir/examples/repairs.sav .], [0])
+
+AT_DATA([barchart.sps], [dnl
+GET FILE="physiology.sav".
+
+GRAPH /BAR = COUNT BY SEX.
+
+GRAPH /BAR = MEAN(height) BY SEX.
+
+NEW FILE.
+
+GET FILE="repairs.sav".
+
+GRAPH /BAR = MEAN (mtbf) BY factory.
+
+COMPUTE R = TRUNC(RV.UNIFORM(1,5)).
+
+GRAPH /BAR = MEAN (mtbf) BY factory BY R.
+])
+
+AT_CHECK([pspp -o pspp.pdf barchart.sps], [0], [ignore])
+dnl Ignore output -- this is just a no-crash check.
+
+AT_CLEANUP
+
+
+
+AT_SETUP([GRAPH barchart arity])
+
+AT_DATA([barchart.sps], [dnl
+data list notable list /x y z*.
+begin data
+1 1 3
+2 1 4
+3 1 3
+4 1 4
+5 . 3
+6 2 4
+7 2 3
+8 2 4
+9 2 3
+10 2 4
+end data.
+
+* This line is invalid
+GRAPH /BAR = COUNT(x) BY y.
+])
+
+AT_CHECK([pspp -o pspp.pdf barchart.sps], [1], [ignore])
+dnl Ignore output -- this is just a no-crash check.
+
+AT_CLEANUP
+
+
+
+
+AT_SETUP([GRAPH barchart bad syntax])
+
+AT_DATA([barchart.sps], [dnl
+data list notable list /x y z*.
+begin data
+1 1 3
+2 1 4
+3 1 3
+4 1 4
+5 . 3
+6 2 4
+7 2 3
+8 2 4
+9 2 3
+10 2 4
+end data.
+
+* This line is invalid
+GRAPH /BAR = SCROD BY y.
+])
+
+AT_CHECK([pspp -o pspp.pdf barchart.sps], [1], [ignore])
+dnl Ignore output -- this is just a no-crash check.
+
+AT_CLEANUP
+
+
+
+AT_SETUP([GRAPH barchart full])
+
+AT_DATA([barchart.sps], [dnl
+data list notable list /x y z*.
+begin data
+1 1 3
+2 1 4
+3 1 3
+4 1 4
+5 . 3
+6 2 4
+7 2 3
+8 2 4
+9 2 3
+10 2 4
+end data.
+
+* This line is invalid
+GRAPH /BAR = COUNT by z.
+GRAPH /BAR = CUFREQ by z.
+GRAPH /BAR = PCT by z.
+GRAPH /BAR = CUPCT by z.
+
+GRAPH /BAR = MEAN(y) BY z.
+GRAPH /BAR = SUM(y) BY z.
+GRAPH /BAR = MAXIMUM(y) BY z.
+GRAPH /BAR = MINIMUM(y) BY z.
+
+GRAPH /BAR = MEAN(y) BY z BY y.
+GRAPH /BAR = SUM(y) BY z BY y.
+GRAPH /BAR = MAXIMUM(y) BY z BY y.
+GRAPH /BAR = MINIMUM(y) BY z BY y.
+])
+
+AT_CHECK([pspp -o pspp.pdf barchart.sps], [0], [ignore])
+dnl Ignore output -- this is just a no-crash check.
+
+AT_CLEANUP
\ No newline at end of file