[goffice] Make histogram able to use raw data.
- From: Jean Bréfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Make histogram able to use raw data.
- Date: Thu, 24 Jun 2010 12:56:14 +0000 (UTC)
commit ec4e808cb0466d797e1e80d86f86fad5076dd4e4
Author: Jean Brefort <jean brefort normalesup org>
Date: Thu Jun 24 14:56:17 2010 +0200
Make histogram able to use raw data.
ChangeLog | 27 ++
pixmaps/Makefile.am | 3 +-
plugins/plot_distrib/Makefile.am | 5 +-
plugins/plot_distrib/gog-boxplot.c | 2 +-
plugins/plot_distrib/gog-histogram.c | 726 ++++++++++++++++++++++++++++---
plugins/plot_distrib/gog-histogram.h | 16 +-
plugins/plot_distrib/plot-types.xml.in | 21 +-
plugins/plot_distrib/plugin.c | 2 +
plugins/plot_distrib/plugin.xml.in | 7 +-
9 files changed, 732 insertions(+), 77 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index f5be74c..652d4b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2010-06-24 Jean Brefort <jean brefort normalesup org>
+
+ * pixmaps/Makefile.am: add new icons.
+ * plugins/plot_distrib/Makefile.am: enhance histograms.
+ * plugins/plot_distrib/gog-boxplot.c (gog_box_plot_pref):
+ * plugins/plot_distrib/gog-histogram.c (gog_histogram_plot_update),
+ (gog_histogram_plot_axis_get_bounds),
+ (gog_histogram_plot_get_property),
+ (gog_histogram_plot_set_property), (vertical_changed_cb),
+ (cumulative_changed_cb), (gog_histogram_plot_populate_editor),
+ (gog_histogram_plot_class_init), (gog_histogram_plot_init),
+ (gog_double_histogram_plot_populate_editor),
+ (gog_double_histogram_plot_finalize),
+ (gog_double_histogram_plot_class_init),
+ (gog_double_histogram_plot_init),
+ (gog_double_histogram_plot_dataset_dims),
+ (gog_double_histogram_plot_dataset_get_elem),
+ (gog_double_histogram_plot_dataset_dim_changed),
+ (gog_double_histogram_plot_dataset_init),
+ (gog_histogram_plot_view_render),
+ (gog_histogram_plot_series_update),
+ (gog_histogram_plot_series_finalize): ditto.
+ * plugins/plot_distrib/gog-histogram.h: ditto.
+ * plugins/plot_distrib/plot-types.xml.in: ditto.
+ * plugins/plot_distrib/plugin.c (go_plugin_init): ditto.
+ * plugins/plot_distrib/plugin.xml.in: ditto.
+
2010-06-16 Morten Welinder <terra gnome org>
* configure.in: Post-release bump.
diff --git a/pixmaps/Makefile.am b/pixmaps/Makefile.am
index a8c919d..821c728 100644
--- a/pixmaps/Makefile.am
+++ b/pixmaps/Makefile.am
@@ -40,7 +40,8 @@ dist_icon_DATA = \
chart_dropbar_1_1.png chart_dropbar_1_2.png \
chart_minmax_1_1.png chart_minmax_1_2.png \
chart_minmax_2_1.png chart_minmax_2_2.png \
- chart_histogram_1_1.png \
+ chart_histogram_1_1.png chart_histogram_2_1.png \
+ chart_histogram_1_3.png chart_histogram_1_4.png \
chart_surface_2_1.png chart_surface_2_2.png \
chart_prob_1_1.png \
\
diff --git a/plugins/plot_distrib/Makefile.am b/plugins/plot_distrib/Makefile.am
index d64808b..7ef3df6 100644
--- a/plugins/plot_distrib/Makefile.am
+++ b/plugins/plot_distrib/Makefile.am
@@ -22,7 +22,10 @@ if WITH_GTK
go-distribution-prefs.c \
go-distribution-prefs.h
endif
-ui_DATA = gog-boxplot-prefs.ui
+ui_DATA = \
+ gog-boxplot-prefs.ui \
+ gog-histogram-prefs.ui \
+ gog-double-histogram-prefs.ui
@INTLTOOL_XML_RULE@
diff --git a/plugins/plot_distrib/gog-boxplot.c b/plugins/plot_distrib/gog-boxplot.c
index d7e5ab4..8ef44b4 100644
--- a/plugins/plot_distrib/gog-boxplot.c
+++ b/plugins/plot_distrib/gog-boxplot.c
@@ -108,7 +108,7 @@ gog_box_plot_pref (GogObject *obj,
GtkWidget *w;
GogBoxPlot *boxplot = GOG_BOX_PLOT (obj);
char const *dir = go_plugin_get_dir_name (
- go_plugins_get_plugin_by_id ("GOffice_plot_boxes"));
+ go_plugins_get_plugin_by_id ("GOffice_plot_distrib"));
char *path = g_build_filename (dir, "gog-boxplot-prefs.ui", NULL);
GtkBuilder *gui = go_gtk_builder_new (path, GETTEXT_PACKAGE, cc);
diff --git a/plugins/plot_distrib/gog-histogram.c b/plugins/plot_distrib/gog-histogram.c
index 1ab1c5f..3ea7378 100644
--- a/plugins/plot_distrib/gog-histogram.c
+++ b/plugins/plot_distrib/gog-histogram.c
@@ -2,7 +2,7 @@
/*
* gog-histogram.c
*
- * Copyright (C) 2005 Jean Brefort (jean brefort normalesup org)
+ * Copyright (C) 2005-2010 Jean Brefort (jean brefort normalesup org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -30,6 +30,7 @@
#include <goffice/math/go-math.h>
#include <goffice/utils/go-format.h>
#include <goffice/utils/go-path.h>
+#include <goffice/utils/go-persist.h>
#include <goffice/utils/go-styled-object.h>
#include <glib/gi18n-lib.h>
#include <gsf/gsf-impl-utils.h>
@@ -41,7 +42,8 @@
typedef struct {
GogSeries base;
GogObject *droplines;
- double *x, *y;
+ double *x, *y, *y_; /* y_ is the second data for double histograms. */
+ double *real_x, *real_y, *real_y_;
} GogHistogramPlotSeries;
typedef GogSeriesClass GogHistogramPlotSeriesClass;
@@ -75,21 +77,26 @@ gog_histogram_plot_update (GogObject *obj)
GogHistogramPlot *model = GOG_HISTOGRAM_PLOT (obj);
GogHistogramPlotSeries *series = GOG_HISTOGRAM_PLOT_SERIES (
model->base.series->data);
- double x_min, x_max, y_min = DBL_MAX, y_max = -DBL_MAX, *x_vals, *y_vals, val;
- unsigned i;
+ double x_min, x_max, y_min = DBL_MAX, y_max = -DBL_MAX, *x_vals = NULL, *y_vals = NULL, val;
+ unsigned i, y_len = 0;
if (!gog_series_is_valid (GOG_SERIES (series)) || series->base.num_elements == 0)
return;
g_free (series->x);
series->x = g_new (double, series->base.num_elements);
- if (series->base.values[0].data != NULL) {
+ if (series->real_x != NULL)
+ x_vals = series->real_x;
+ else if (series->base.values[0].data != NULL)
x_vals = go_data_get_values (series->base.values[0].data);
+ if (x_vals != NULL) {
x_min = x_vals[0];
x_max = x_vals[series->base.num_elements];
- if (model->x.fmt == NULL)
- model->x.fmt = go_data_preferred_fmt (series->base.values[0].data);
- model->x.date_conv = go_data_date_conv (series->base.values[0].data);
+ if (series->base.values[0].data) {
+ if (model->x.fmt == NULL)
+ model->x.fmt = go_data_preferred_fmt (series->base.values[0].data);
+ model->x.date_conv = go_data_date_conv (series->base.values[0].data);
+ }
for (i = 0; i < series->base.num_elements; i++)
series->x[i] = (x_vals[i] + x_vals[i+1]) / 2;
} else {
@@ -102,35 +109,80 @@ gog_histogram_plot_update (GogObject *obj)
if (model->x.minima != x_min || model->x.maxima != x_max) {
model->x.minima = x_min;
model->x.maxima = x_max;
- gog_axis_bound_changed (model->base.axis[0], GOG_OBJECT (model));
+ gog_axis_bound_changed (model->base.axis[model->vertical? 0: 1], GOG_OBJECT (model));
}
g_free (series->y);
series->y = NULL;
- if (series->base.values[1].data != NULL) {
- if (x_vals) {
- series->y = g_new (double, series->base.num_elements);
+ if (series->real_y != NULL) {
+ y_vals = series->real_y;
+ y_len = series->base.num_elements;
+ } else if (series->base.values[1].data != NULL) {
+ y_vals = go_data_get_values (series->base.values[1].data);
+ y_len = go_data_get_vector_size (series->base.values[1].data);
+ if (y_len > series->base.num_elements)
+ y_len = series->base.num_elements;
+ }
+ if (y_vals != NULL) {
+ double sum = 0.;
+ series->y = g_new0 (double, series->base.num_elements);
+ for (i = 0; i < y_len; i++)
+ if (go_finite (y_vals[i])) {
+ if (model->cumulative)
+ sum += y_vals[i];
+ else
+ sum = y_vals[i];
+ series->y[i] = val = sum / (x_vals[i+1] - x_vals[i]);
+ if (val < y_min)
+ y_min = val;
+ if (val > y_max)
+ y_max = val;
+ } else
+ series->y[i] = (model->cumulative)? sum: 0.;
+ if (model->y.fmt == NULL)
+ model->y.fmt = go_data_preferred_fmt (series->base.values[1].data);
+ model->y.date_conv = go_data_date_conv (series->base.values[1].data);
+ }
+ if (GOG_IS_DOUBLE_HISTOGRAM_PLOT (model) && series->base.values[2].data != NULL) {
+ double max = 0.;
+ g_free (series->y_);
+ series->y_ = NULL;
+ if (series->real_y_ != NULL) {
+ y_vals = series->real_y_;
+ y_len = series->base.num_elements;
+ } else if (series->base.values[1].data != NULL) {
y_vals = go_data_get_values (series->base.values[1].data);
- for (i = 0; i < series->base.num_elements; i++)
+ y_len = go_data_get_vector_size (series->base.values[1].data);
+ if (y_len > series->base.num_elements)
+ y_len = series->base.num_elements;
+ } else
+ y_vals = NULL;
+ if (y_vals != NULL) {
+ double sum = 0.;
+ y_min = 0.;
+ series->y_ = g_new0 (double, series->base.num_elements);
+ for (i = 0; i < y_len; i++)
if (go_finite (y_vals[i])) {
- series->y[i] = val = y_vals[i] / (x_vals[i+1] - x_vals[i]);
+ if (model->cumulative)
+ sum += y_vals[i];
+ else
+ sum = y_vals[i];
+ series->y_[i] = val = -sum / (x_vals[i+1] - x_vals[i]);
if (val < y_min)
y_min = val;
- if (val > y_max)
- y_max = val;
+ if (val > max)
+ max = val;
} else
- series->y[i] = 0.;
- } else
- go_data_get_bounds (series->base.values[1].data, &y_min, &y_max);
- if (model->y.fmt == NULL)
- model->y.fmt = go_data_preferred_fmt (series->base.values[1].data);
- model->y.date_conv = go_data_date_conv (series->base.values[1].data);
+ series->y_[i] = (model->cumulative)? sum: 0.;
+ }
+ if (y_max < 0)
+ y_max = max;
}
if (y_min > y_max)
y_min = y_max = go_nan;
if (model->y.minima != y_min || model->y.maxima != y_max) {
model->y.minima = y_min;
model->y.maxima = y_max;
- gog_axis_bound_changed (model->base.axis[1], GOG_OBJECT (model));
+ gog_axis_bound_changed (model->base.axis[model->vertical? 1: 0], GOG_OBJECT (model));
}
gog_object_emit_changed (GOG_OBJECT (obj), FALSE);
}
@@ -142,7 +194,7 @@ gog_histogram_plot_axis_get_bounds (GogPlot *plot, GogAxisType axis,
GogHistogramPlot *model = GOG_HISTOGRAM_PLOT (plot);
- if (axis == GOG_AXIS_X) {
+ if ((axis == GOG_AXIS_X && model->vertical) || (axis == GOG_AXIS_Y && !model->vertical)) {
bounds->val.minima = model->x.minima;
bounds->val.maxima = model->x.maxima;
if (bounds->fmt == NULL && model->x.fmt != NULL)
@@ -161,6 +213,111 @@ gog_histogram_plot_axis_get_bounds (GogPlot *plot, GogAxisType axis,
return NULL;
}
+enum {
+ HISTOGRAM_PROP_0,
+ HISTOGRAM_PROP_VERTICAL,
+ HISTOGRAM_PROP_CUMULATIVE
+};
+
+static void
+gog_histogram_plot_get_property (GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GogHistogramPlot *model = GOG_HISTOGRAM_PLOT (obj);
+ switch (param_id) {
+ case HISTOGRAM_PROP_VERTICAL:
+ g_value_set_boolean (value, model->vertical);
+ break;
+ case HISTOGRAM_PROP_CUMULATIVE:
+ g_value_set_boolean (value, model->cumulative);
+ break;
+
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+gog_histogram_plot_set_property (GObject *obj, guint param_id,
+ GValue const *value, GParamSpec *pspec)
+{
+ GogHistogramPlot *model = GOG_HISTOGRAM_PLOT (obj);
+ switch (param_id) {
+ case HISTOGRAM_PROP_VERTICAL:
+ if (g_value_get_boolean (value) != model->vertical) {
+ model->vertical = !model->vertical;
+ /* force axis bounds reevaluation */
+ model->x.minima = model->y.minima = G_MAXDOUBLE;
+ gog_object_request_update (GOG_OBJECT (model));
+ }
+ break;
+ case HISTOGRAM_PROP_CUMULATIVE:
+ if (g_value_get_boolean (value) != model->cumulative) {
+ model->cumulative = !model->cumulative;
+ gog_object_request_update (GOG_OBJECT (model));
+ }
+ break;
+
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ return; /* NOTE : RETURN */
+ }
+}
+
+#ifdef GOFFICE_WITH_GTK
+#include <goffice/gtk/goffice-gtk.h>
+
+static void
+vertical_changed_cb (GtkToggleButton *btn, GogHistogramPlot *model)
+{
+ if (gtk_toggle_button_get_active (btn) != model->vertical) {
+ model->vertical = !model->vertical;
+ gog_object_request_update (GOG_OBJECT (model));
+ /* force axis bounds reevaluation */
+ model->x.minima = model->y.minima = G_MAXDOUBLE;
+ }
+}
+
+static void
+cumulative_changed_cb (GtkToggleButton *btn, GogHistogramPlot *model)
+{
+ if (gtk_toggle_button_get_active (btn) != model->cumulative) {
+ model->cumulative = !model->cumulative;
+ gog_object_request_update (GOG_OBJECT (model));
+ }
+}
+
+static void
+gog_histogram_plot_populate_editor (GogObject *item,
+ GOEditor *editor,
+ G_GNUC_UNUSED GogDataAllocator *dalloc,
+ GOCmdContext *cc)
+{
+ GtkWidget *w;
+ GogHistogramPlot *hist = GOG_HISTOGRAM_PLOT (item);
+ char const *dir = go_plugin_get_dir_name (
+ go_plugins_get_plugin_by_id ("GOffice_plot_distrib"));
+ char *path = g_build_filename (dir, "gog-histogram-prefs.ui", NULL);
+ GtkBuilder *gui = go_gtk_builder_new (path, GETTEXT_PACKAGE, cc);
+
+ g_free (path);
+ if (gui != NULL) {
+ w = go_gtk_builder_get_widget (gui, "vertical");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), hist->vertical);
+ g_signal_connect (w, "toggled", G_CALLBACK (vertical_changed_cb), hist);
+
+ w = go_gtk_builder_get_widget (gui, "cumulative");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), hist->cumulative);
+ g_signal_connect (w, "toggled", G_CALLBACK (cumulative_changed_cb), hist);
+
+ w = go_gtk_builder_get_widget (gui, "histogram-prefs");
+ go_editor_add_page (editor, w , _("Properties"));
+ g_object_unref (gui);
+ }
+
+ (GOG_OBJECT_CLASS(histogram_plot_parent_klass)->populate_editor) (item, editor, dalloc, cc);
+}
+#endif
+
static void
gog_histogram_plot_finalize (GObject *obj)
{
@@ -173,31 +330,48 @@ gog_histogram_plot_class_init (GogPlotClass *gog_plot_klass)
{
GObjectClass *gobject_klass = (GObjectClass *) gog_plot_klass;
GogObjectClass *gog_object_klass = (GogObjectClass *) gog_plot_klass;
- GogPlotClass *plot_klass = (GogPlotClass *) gog_plot_klass;
histogram_plot_parent_klass = g_type_class_peek_parent (gog_plot_klass);
gobject_klass->finalize = gog_histogram_plot_finalize;
+ gobject_klass->get_property = gog_histogram_plot_get_property;
+ gobject_klass->set_property = gog_histogram_plot_set_property;
+
+ g_object_class_install_property (gobject_klass, HISTOGRAM_PROP_VERTICAL,
+ g_param_spec_boolean ("vertical",
+ _("Vertical"),
+ _("Draw the histogram vertically or horizontally"),
+ TRUE,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+ g_object_class_install_property (gobject_klass, HISTOGRAM_PROP_CUMULATIVE,
+ g_param_spec_boolean ("cumulative",
+ _("Cumulative"),
+ _("Use cumulated data"),
+ FALSE,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
gog_object_klass->type_name = gog_histogram_plot_type_name;
gog_object_klass->view_type = gog_histogram_plot_view_get_type ();
gog_object_klass->update = gog_histogram_plot_update;
+#ifdef GOFFICE_WITH_GTK
+ gog_object_klass->populate_editor = gog_histogram_plot_populate_editor;
+#endif
{
static GogSeriesDimDesc dimensions[] = {
- { N_("Limits"), GOG_SERIES_REQUIRED, FALSE,
+ { N_("Limits"), GOG_SERIES_SUGGESTED, FALSE,
GOG_DIM_INDEX, GOG_MS_DIM_CATEGORIES },
{ N_("Values"), GOG_SERIES_REQUIRED, FALSE,
GOG_DIM_VALUE, GOG_MS_DIM_VALUES },
};
- plot_klass->desc.series.dim = dimensions;
- plot_klass->desc.series.num_dim = G_N_ELEMENTS (dimensions);
+ gog_plot_klass->desc.series.dim = dimensions;
+ gog_plot_klass->desc.series.num_dim = G_N_ELEMENTS (dimensions);
}
- plot_klass->desc.num_series_max = 1;
- plot_klass->series_type = gog_histogram_plot_series_get_type ();
- plot_klass->axis_set = GOG_AXIS_SET_XY;
- plot_klass->desc.series.style_fields = GO_STYLE_OUTLINE | GO_STYLE_FILL;
- plot_klass->axis_get_bounds = gog_histogram_plot_axis_get_bounds;
+ gog_plot_klass->desc.num_series_max = 1;
+ gog_plot_klass->series_type = gog_histogram_plot_series_get_type ();
+ gog_plot_klass->axis_set = GOG_AXIS_SET_XY;
+ gog_plot_klass->desc.series.style_fields = GO_STYLE_OUTLINE | GO_STYLE_FILL;
+ gog_plot_klass->axis_get_bounds = gog_histogram_plot_axis_get_bounds;
}
static void
@@ -206,6 +380,7 @@ gog_histogram_plot_init (GogHistogramPlot *hist)
GogPlot *plot = GOG_PLOT (hist);
plot->render_before_axes = TRUE;
+ hist->vertical = TRUE;
}
GSF_DYNAMIC_CLASS (GogHistogramPlot, gog_histogram_plot,
@@ -213,6 +388,124 @@ GSF_DYNAMIC_CLASS (GogHistogramPlot, gog_histogram_plot,
GOG_TYPE_PLOT)
/*****************************************************************************/
+/* Double histograms */
+
+static GObjectClass *double_histogram_plot_parent_klass;
+
+#ifdef GOFFICE_WITH_GTK
+static void
+gog_double_histogram_plot_populate_editor (GogObject *gobj,
+ GOEditor *editor,
+ GogDataAllocator *dalloc,
+ GOCmdContext *cc)
+{
+ GtkTable *table;
+ GtkWidget *w;
+ GogDataset *set = GOG_DATASET (gobj);
+ char const *dir = go_plugin_get_dir_name (
+ go_plugins_get_plugin_by_id ("GOffice_plot_distrib"));
+ char *path = g_build_filename (dir, "gog-double-histogram-prefs.ui", NULL);
+ GtkBuilder *gui = go_gtk_builder_new (path, GETTEXT_PACKAGE, cc);
+
+ g_free (path);
+
+ if (gui != NULL) {
+ table = GTK_TABLE (gtk_builder_get_object (gui, "double-histogram-prefs"));
+ w = GTK_WIDGET (gog_data_allocator_editor (dalloc, set, 0, GOG_DATA_SCALAR));
+ gtk_widget_set_tooltip_text (w, _("Label for the first Y category. If not set or empty, \"First values\" will be used."));
+ gtk_widget_show (w);
+ gtk_table_attach (table, w, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ w = GTK_WIDGET (gog_data_allocator_editor (dalloc, set, 1, GOG_DATA_SCALAR));
+ gtk_widget_set_tooltip_text (w, _("Label for the second Y category. If not set or empty, \"Second values\" will be used."));
+ gtk_widget_show (w);
+ gtk_table_attach (table, w, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ go_editor_add_page (editor,
+ go_gtk_builder_get_widget (gui, "double-histogram-prefs"),
+ _("Categories labels"));
+ }
+ (GOG_OBJECT_CLASS (double_histogram_plot_parent_klass)->populate_editor) (gobj, editor, dalloc, cc);
+}
+#endif
+
+static void
+gog_double_histogram_plot_finalize (GObject *obj)
+{
+ GogDoubleHistogramPlot *plot = GOG_DOUBLE_HISTOGRAM_PLOT (obj);
+ if (plot->labels != NULL) {
+ gog_dataset_finalize (GOG_DATASET (obj));
+ g_free (plot->labels);
+ plot->labels = NULL;
+ }
+ (*double_histogram_plot_parent_klass->finalize) (obj);
+}
+
+static void
+gog_double_histogram_plot_class_init (GogPlotClass *gog_plot_klass)
+{
+ GObjectClass *gobject_klass = (GObjectClass *) gog_plot_klass;
+ GogObjectClass *gog_klass = (GogObjectClass *) gog_plot_klass;
+ double_histogram_plot_parent_klass = g_type_class_peek_parent (gog_klass);
+ gobject_klass->finalize = gog_double_histogram_plot_finalize;
+#ifdef GOFFICE_WITH_GTK
+ gog_klass->populate_editor = gog_double_histogram_plot_populate_editor;
+#endif
+ {
+ static GogSeriesDimDesc dimensions[] = {
+ { N_("Limits"), GOG_SERIES_REQUIRED, FALSE,
+ GOG_DIM_INDEX, GOG_MS_DIM_CATEGORIES },
+ { N_("First values"), GOG_SERIES_REQUIRED, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_VALUES },
+ { N_("Second values"), GOG_SERIES_REQUIRED, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_EXTRA1 },
+ };
+ gog_plot_klass->desc.series.dim = dimensions;
+ gog_plot_klass->desc.series.num_dim = G_N_ELEMENTS (dimensions);
+ gog_plot_klass->desc.series.style_fields = GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT;
+ }
+}
+
+static void
+gog_double_histogram_plot_init (GogDoubleHistogramPlot *plot)
+{
+ plot->labels = g_new0 (GogDatasetElement, 2);
+}
+
+static void
+gog_double_histogram_plot_dataset_dims (GogDataset const *set, int *first, int *last)
+{
+ *first = 0;
+ *last = 1;
+}
+
+static GogDatasetElement *
+gog_double_histogram_plot_dataset_get_elem (GogDataset const *set, int dim_i)
+{
+ GogDoubleHistogramPlot const *plot = GOG_DOUBLE_HISTOGRAM_PLOT (set);
+ g_return_val_if_fail (2 > dim_i, NULL);
+ g_return_val_if_fail (dim_i >= 0, NULL);
+ return plot->labels + dim_i;
+}
+
+static void
+gog_double_histogram_plot_dataset_dim_changed (GogDataset *set, int dim_i)
+{
+ gog_object_request_update (GOG_OBJECT (set));
+}
+
+static void
+gog_double_histogram_plot_dataset_init (GogDatasetClass *iface)
+{
+ iface->get_elem = gog_double_histogram_plot_dataset_get_elem;
+ iface->dims = gog_double_histogram_plot_dataset_dims;
+ iface->dim_changed = gog_double_histogram_plot_dataset_dim_changed;
+}
+
+GSF_DYNAMIC_CLASS_FULL (GogDoubleHistogramPlot, gog_double_histogram_plot,
+ NULL, NULL, gog_double_histogram_plot_class_init, NULL,
+ gog_double_histogram_plot_init, GOG_TYPE_HISTOGRAM_PLOT, 0,
+ GSF_INTERFACE (gog_double_histogram_plot_dataset_init, GOG_TYPE_DATASET))
+
+/*****************************************************************************/
typedef GogPlotView GogHistogramPlotView;
typedef GogPlotViewClass GogHistogramPlotViewClass;
@@ -251,21 +544,36 @@ gog_histogram_plot_view_render (GogView *view, GogViewAllocation const *bbox)
x_map = gog_chart_map_get_axis_map (chart_map, 0);
y_map = gog_chart_map_get_axis_map (chart_map, 1);
- if (series->base.values[0].data)
+ if (series->real_x)
+ x_vals = series->real_x;
+ else if (series->base.values[0].data)
x_vals = go_data_get_values (series->base.values[0].data);
- y_vals = (x_vals)? series->y: go_data_get_values (series->base.values[1].data);
+ y_vals = (series->y)? series->y: go_data_get_values (series->base.values[1].data);
path = go_path_new ();
go_path_set_options (path, GO_PATH_OPTIONS_SHARP);
- curx = gog_axis_map_to_view (x_map, ((x_vals)? x_vals[0]: 0.));
- go_path_move_to (path, curx, y0 = gog_axis_map_get_baseline (y_map));
- for (i = 0, j = 1; i < series->base.num_elements; i++) {
- cury = gog_axis_map_to_view (y_map, y_vals[i]);
- go_path_line_to (path, curx, cury);
- curx = gog_axis_map_to_view (x_map, ((x_vals)? x_vals[i+1]: 0.));
- go_path_line_to (path, curx, cury);
+ if (model->vertical) {
+ curx = gog_axis_map_to_view (x_map, ((x_vals)? x_vals[0]: 0.));
+ go_path_move_to (path, curx, y0 = gog_axis_map_get_baseline (y_map));
+ for (i = 0, j = 1; i < series->base.num_elements; i++) {
+ cury = gog_axis_map_to_view (y_map, y_vals[i]);
+ go_path_line_to (path, curx, cury);
+ curx = gog_axis_map_to_view (x_map, ((x_vals)? x_vals[i+1]: 0.));
+ go_path_line_to (path, curx, cury);
+ }
+ go_path_line_to (path, curx, y0);
+ } else {
+ curx = gog_axis_map_to_view (y_map, ((x_vals)? x_vals[0]: 0.));
+ go_path_move_to (path, y0 = gog_axis_map_get_baseline (x_map), curx);
+ for (i = 0, j = 1; i < series->base.num_elements; i++) {
+ cury = gog_axis_map_to_view (x_map, y_vals[i]);
+ go_path_line_to (path, cury, curx);
+ curx = gog_axis_map_to_view (y_map, ((x_vals)? x_vals[i+1]: 0.));
+ go_path_line_to (path, cury, curx);
+ }
+ go_path_line_to (path, y0, curx);
}
- go_path_line_to (path, curx, y0);
+ go_path_close (path);
gog_renderer_push_style (view->renderer, style);
gog_renderer_fill_shape (view->renderer, path);
@@ -275,23 +583,42 @@ gog_histogram_plot_view_render (GogView *view, GogViewAllocation const *bbox)
gog_renderer_push_style (view->renderer,
go_styled_object_get_style (GO_STYLED_OBJECT (series->droplines)));
cury = y0;
- for (i = 1; i < series->base.num_elements; i++) {
- curx = gog_axis_map_to_view (x_map, ((x_vals)? x_vals[i]: 0.));
- if (y_vals[i-1] * y_vals[i] > 0.) {
- go_path_move_to (drop_path, curx, y0);
- if (y_vals[i] > 0.)
- cury = gog_axis_map_to_view (y_map,
- MIN (y_vals[i-1], y_vals[i]));
- else
- cury = gog_axis_map_to_view (y_map,
- MAX (y_vals[i-1], y_vals[i]));
-
- } else {
- go_path_move_to (drop_path, curx, cury);
- cury = gog_axis_map_to_view (y_map, y_vals[i]);
+ if (model->vertical)
+ for (i = 1; i < series->base.num_elements; i++) {
+ curx = gog_axis_map_to_view (x_map, ((x_vals)? x_vals[i]: 0.));
+ if (y_vals[i-1] * y_vals[i] > 0.) {
+ go_path_move_to (drop_path, curx, y0);
+ if (y_vals[i] > 0.)
+ cury = gog_axis_map_to_view (y_map,
+ MIN (y_vals[i-1], y_vals[i]));
+ else
+ cury = gog_axis_map_to_view (y_map,
+ MAX (y_vals[i-1], y_vals[i]));
+
+ } else {
+ go_path_move_to (drop_path, curx, cury);
+ cury = gog_axis_map_to_view (y_map, y_vals[i]);
+ }
+ go_path_line_to (drop_path, curx, cury);
+ }
+ else
+ for (i = 1; i < series->base.num_elements; i++) {
+ curx = gog_axis_map_to_view (y_map, ((x_vals)? x_vals[i]: 0.));
+ if (y_vals[i-1] * y_vals[i] > 0.) {
+ go_path_move_to (drop_path, y0, curx);
+ if (y_vals[i] > 0.)
+ cury = gog_axis_map_to_view (x_map,
+ MIN (y_vals[i-1], y_vals[i]));
+ else
+ cury = gog_axis_map_to_view (x_map,
+ MAX (y_vals[i-1], y_vals[i]));
+
+ } else {
+ go_path_move_to (drop_path, cury, curx);
+ cury = gog_axis_map_to_view (x_map, y_vals[i]);
+ }
+ go_path_line_to (drop_path, cury, curx);
}
- go_path_line_to (drop_path, curx, cury);
- }
gog_renderer_stroke_serie (view->renderer, drop_path);
go_path_free (drop_path);
gog_renderer_pop_style (view->renderer);
@@ -299,6 +626,147 @@ gog_histogram_plot_view_render (GogView *view, GogViewAllocation const *bbox)
gog_renderer_stroke_shape (view->renderer, path);
gog_renderer_pop_style (view->renderer);
go_path_free (path);
+ /* Redo the same for the other side of a double histogram. */
+ if (GOG_IS_DOUBLE_HISTOGRAM_PLOT (model) && series->base.values[2].data != NULL) {
+ y_vals = (series->y_)? series->y_: go_data_get_values (series->base.values[2].data);
+ path = go_path_new ();
+ go_path_set_options (path, GO_PATH_OPTIONS_SHARP);
+ if (model->vertical) {
+ curx = gog_axis_map_to_view (x_map, ((x_vals)? x_vals[0]: 0.));
+ go_path_move_to (path, curx, y0);
+ for (i = 0, j = 1; i < series->base.num_elements; i++) {
+ cury = gog_axis_map_to_view (y_map, y_vals[i]);
+ go_path_line_to (path, curx, cury);
+ curx = gog_axis_map_to_view (x_map, ((x_vals)? x_vals[i+1]: 0.));
+ go_path_line_to (path, curx, cury);
+ }
+ go_path_line_to (path, curx, y0);
+ } else {
+ curx = gog_axis_map_to_view (y_map, ((x_vals)? x_vals[0]: 0.));
+ go_path_move_to (path, y0, curx);
+ for (i = 0, j = 1; i < series->base.num_elements; i++) {
+ cury = gog_axis_map_to_view (x_map, y_vals[i]);
+ go_path_line_to (path, cury, curx);
+ curx = gog_axis_map_to_view (y_map, ((x_vals)? x_vals[i+1]: 0.));
+ go_path_line_to (path, cury, curx);
+ }
+ go_path_line_to (path, y0, curx);
+ }
+ go_path_close (path);
+ gog_renderer_push_style (view->renderer, style);
+ gog_renderer_fill_shape (view->renderer, path);
+
+ if (series->droplines) {
+ GOPath *drop_path = go_path_new ();
+ go_path_set_options (drop_path, GO_PATH_OPTIONS_SHARP);
+ gog_renderer_push_style (view->renderer,
+ go_styled_object_get_style (GO_STYLED_OBJECT (series->droplines)));
+ cury = y0;
+ if (model->vertical)
+ for (i = 1; i < series->base.num_elements; i++) {
+ curx = gog_axis_map_to_view (x_map, ((x_vals)? x_vals[i]: 0.));
+ if (y_vals[i-1] * y_vals[i] > 0.) {
+ go_path_move_to (drop_path, curx, y0);
+ if (y_vals[i] > 0.)
+ cury = gog_axis_map_to_view (y_map,
+ MIN (y_vals[i-1], y_vals[i]));
+ else
+ cury = gog_axis_map_to_view (y_map,
+ MAX (y_vals[i-1], y_vals[i]));
+
+ } else {
+ go_path_move_to (drop_path, curx, cury);
+ cury = gog_axis_map_to_view (y_map, y_vals[i]);
+ }
+ go_path_line_to (drop_path, curx, cury);
+ }
+ else
+ for (i = 1; i < series->base.num_elements; i++) {
+ curx = gog_axis_map_to_view (y_map, ((x_vals)? x_vals[i]: 0.));
+ if (y_vals[i-1] * y_vals[i] > 0.) {
+ go_path_move_to (drop_path, y0, curx);
+ if (y_vals[i] > 0.)
+ cury = gog_axis_map_to_view (x_map,
+ MIN (y_vals[i-1], y_vals[i]));
+ else
+ cury = gog_axis_map_to_view (x_map,
+ MAX (y_vals[i-1], y_vals[i]));
+
+ } else {
+ go_path_move_to (drop_path, cury, curx);
+ cury = gog_axis_map_to_view (x_map, y_vals[i]);
+ }
+ go_path_line_to (drop_path, cury, curx);
+ }
+ gog_renderer_stroke_serie (view->renderer, drop_path);
+ go_path_free (drop_path);
+ gog_renderer_pop_style (view->renderer);
+ }
+ gog_renderer_stroke_shape (view->renderer, path);
+ go_path_free (path);
+
+ /* Now display labels FIXME: might be optional */
+ {
+ char *text1 = NULL, *text2 = NULL;
+ char const *text;
+ GogViewAllocation alloc;
+ GogDoubleHistogramPlot *dbl = GOG_DOUBLE_HISTOGRAM_PLOT (model);
+ if (dbl->labels[0].data) {
+ text1 = go_data_get_scalar_string (dbl->labels[0].data);
+ if (text1 && !*text1) {
+ g_free (text1);
+ text1 = NULL;
+ }
+ }
+ if (dbl->labels[1].data) {
+ text2 = go_data_get_scalar_string (dbl->labels[1].data);
+ if (text2 && !*text2) {
+ g_free (text2);
+ text2 = NULL;
+ }
+ }
+ text = (text1)? text1: _("First values");
+ if (model->cumulative) {
+ if (model->vertical) {
+ alloc.x = area->x + 2; /* FIXME: replace 2 by something configurable */
+ alloc.y = area->y + 2;
+ gog_renderer_draw_text (view->renderer, text, &alloc,
+ GTK_ANCHOR_NORTH_WEST, FALSE);
+ text = (text2)? text2: _("Second values");
+ alloc.y = area->y + area->h - 2;
+ gog_renderer_draw_text (view->renderer, text, &alloc,
+ GTK_ANCHOR_SOUTH_WEST, FALSE);
+ } else {
+ alloc.x = area->x + area->w - 2; /* FIXME: replace 2 by something configurable */
+ alloc.y = area->y + area->h - 2;
+ gog_renderer_draw_text (view->renderer, text, &alloc,
+ GTK_ANCHOR_SOUTH_EAST, FALSE);
+ text = (text2)? text2: _("Second values");
+ alloc.x = area->x + 2;
+ gog_renderer_draw_text (view->renderer, text, &alloc,
+ GTK_ANCHOR_SOUTH_WEST, FALSE);
+ }
+ } else {
+ alloc.x = area->x + area->w - 2; /* FIXME: replace 2 by something configurable */
+ alloc.y = area->y + 2;
+ gog_renderer_draw_text (view->renderer, text, &alloc,
+ GTK_ANCHOR_NORTH_EAST, FALSE);
+ text = (text2)? text2: _("Second values");
+ if (model->vertical) {
+ alloc.y = area->y + area->h - 2;
+ gog_renderer_draw_text (view->renderer, text, &alloc,
+ GTK_ANCHOR_SOUTH_EAST, FALSE);
+ } else {
+ alloc.x = area->x + 2;
+ gog_renderer_draw_text (view->renderer, text, &alloc,
+ GTK_ANCHOR_NORTH_WEST, FALSE);
+ }
+ }
+ g_free (text1);
+ g_free (text2);
+ }
+ gog_renderer_pop_style (view->renderer);
+ }
/* Now render children */
for (ptr = view->children ; ptr != NULL ; ptr = ptr->next)
gog_view_render (ptr->data, bbox);
@@ -402,32 +870,140 @@ static GObjectClass *series_parent_klass;
static void
gog_histogram_plot_series_update (GogObject *obj)
{
- double *x_vals = NULL, *y_vals = NULL, cur;
- int x_len = 1, y_len = 0, i, max;
+ double *x_vals = NULL, *y_vals = NULL, *y__vals = NULL, cur;
+ int x_len = 1, y_len = 0, y__len = 0, max, nb = 0, i;
GogHistogramPlotSeries *series = GOG_HISTOGRAM_PLOT_SERIES (obj);
unsigned old_num = series->base.num_elements;
GSList *ptr;
-
+ gboolean y_as_raw = FALSE;
+ double width = -1., origin = 0.;
+
+ g_free (series->real_x);
+ series->real_x = NULL;
+ g_free (series->real_y);
+ series->real_y = NULL;
+ g_free (series->real_y_);
+ series->real_y_ = NULL;
if (series->base.values[1].data != NULL) {
y_vals = go_data_get_values (series->base.values[1].data);
- y_len = go_data_get_vector_size (series->base.values[1].data);
+ nb = y_len = go_data_get_vector_size (series->base.values[1].data);
+ }
+ if (GOG_IS_DOUBLE_HISTOGRAM_PLOT (series->base.plot) && series->base.values[2].data != NULL) {
+ y__vals = go_data_get_values (series->base.values[2].data);
+ y__len = go_data_get_vector_size (series->base.values[2].data);
+ if (y__len > y_len)
+ nb = y__len;
}
if (series->base.values[0].data != NULL) {
x_vals = go_data_get_values (series->base.values[0].data);
max = go_data_get_vector_size (series->base.values[0].data);
- if (max > 0 && go_finite (x_vals[0])) {
- cur = x_vals[0];
- for (i = 1; i< max; i++) {
- if (go_finite (x_vals[i]) && x_vals[i] > cur) {
- cur = x_vals[i];
- x_len++;
- } else
- break;
+ if (max == 2) {
+ origin = x_vals[1];
+ max = 1;
+ }
+ if (max == 1) {
+ /* use the value as bin width */
+ width = x_vals[0];
+ if (!go_finite (width))
+ width = -1.;
+ y_as_raw = TRUE;
+ } else if (max > nb) {
+ if (max > 0 && go_finite (x_vals[0])) {
+ cur = x_vals[0];
+ for (i = 1; i < max; i++) {
+ if (go_finite (x_vals[i]) && x_vals[i] > cur) {
+ cur = x_vals[i];
+ x_len++;
+ } else
+ break;
+ }
}
+ } else {
+ x_len = max;
+ y_as_raw = TRUE;
}
} else
- x_len = y_len + 1;
- series->base.num_elements = MIN (x_len - 1, y_len);
+ y_as_raw = TRUE;
+ if (y_as_raw) {
+ double *y = NULL, *y_ = NULL;
+ if (y_vals) {
+ y = go_range_sort (y_vals, y_len);
+ }
+ if (y__vals) {
+ y_ = go_range_sort (y__vals, y__len);
+ }
+ if (!x_vals || x_len <= 1) {
+ /* guess reasonable values */
+ if (width <= 0) {
+ max = go_fake_round (sqrt (MAX (y_len, y__len)));
+ if (y && y_len > 2)
+ width = (y[y_len-1] - y[0]) / max;
+ if (y_ && y__len > 2) {
+ double w_ = (y_[y__len-1] - y_[0]) / max;
+ width = MAX (width, w_);
+ }
+ if (width > 0.) {
+ width = log10 (width);
+ max = floor (width);
+ width -= max;
+ if (width < 0.15)
+ width = pow (10, max);
+ else if (width < 0.45)
+ width = 2 * pow (10, max);
+ else if (width < 0.85)
+ width = 2 * pow (10, max);
+ else
+ width = pow (10, max + 1);
+ }
+ }
+ if (width > 0. && (y || y_)) {
+ double m, M;
+ if (y) {
+ m = (y_)? (MIN (y[0], y_[0])): y[0];
+ M = (y_)? (MAX (y[y_len-1], y_[y__len-1])): y[y_len-1];
+ } else {
+ m = y_[0];
+ M = y_[y__len-1];
+ }
+ /* round m */
+ m = floor ((m - origin)/ width) * width + origin;
+ x_len = ceil ((M - m) / width) + 1;
+ series->real_x = g_new (double, x_len);
+ for (max = 0; max < x_len; max++) {
+ series->real_x[max] = m;
+ m += width;
+ }
+ }
+ } else
+ series->real_x = go_range_sort (x_vals, x_len);
+ if (x_len > 1) {
+ series->real_y = g_new0 (double, x_len - 1);
+ for (i = 0; i < y_len && y[i] <= series->real_x[0]; i++);
+ for (max = 1; i < y_len; i++)
+ if (go_finite (y[i])) {
+ while (y[i] > series->real_x[max]) {
+ max++;
+ if (max == x_len - 1)
+ break;
+ }
+ series->real_y[max-1]++;
+ }
+ if (y__len > 0) {
+ series->real_y_ = g_new0 (double, x_len - 1);
+ for (i = 0; i < y__len && y_[i] <= series->real_x[0]; i++);
+ for (max = 1; i < y__len; i++)
+ if (go_finite (y_[i])) {
+ while (y_[i] > series->real_x[max]) {
+ max++;
+ if (max == x_len - 1)
+ break;
+ }
+ series->real_y_[max-1]++;
+ }
+ }
+ }
+ }
+ series->base.num_elements = (x_len > 0)? MIN (x_len - 1, nb): 0;
/* update children */
for (ptr = obj->children; ptr != NULL; ptr = ptr->next)
@@ -450,8 +1026,16 @@ gog_histogram_plot_series_finalize (GObject *obj)
g_free (series->y);
series->y = NULL;
+ g_free (series->y_);
+ series->y_ = NULL;
g_free (series->x);
series->x = NULL;
+ g_free (series->real_x);
+ series->real_x = NULL;
+ g_free (series->real_y);
+ series->real_y = NULL;
+ g_free (series->real_y_);
+ series->real_y_ = NULL;
G_OBJECT_CLASS (series_parent_klass)->finalize (obj);
}
diff --git a/plugins/plot_distrib/gog-histogram.h b/plugins/plot_distrib/gog-histogram.h
index 43a7a38..a4f0f8f 100644
--- a/plugins/plot_distrib/gog-histogram.h
+++ b/plugins/plot_distrib/gog-histogram.h
@@ -2,7 +2,7 @@
/*
* gog-histogram.h
*
- * Copyright (C) 2005 Jean Brefort (jean brefort normalesup org)
+ * Copyright (C) 2005-2010 Jean Brefort (jean brefort normalesup org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -34,6 +34,8 @@ typedef struct {
GOFormat *fmt;
GODateConventions const *date_conv;
} x, y;
+ gboolean vertical;
+ gboolean cumulative;
} GogHistogramPlot;
typedef GogPlotClass GogHistogramPlotClass;
@@ -43,6 +45,18 @@ typedef GogPlotClass GogHistogramPlotClass;
GType gog_histogram_plot_get_type (void);
+typedef struct {
+ GogHistogramPlot base;
+ GogDatasetElement *labels; /* labels for the two y categories */
+} GogDoubleHistogramPlot;
+typedef GogHistogramPlotClass GogDoubleHistogramPlotClass;
+
+#define GOG_DOUBLE_HISTOGRAM_PLOT_TYPE (gog_double_histogram_plot_get_type ())
+#define GOG_DOUBLE_HISTOGRAM_PLOT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_DOUBLE_HISTOGRAM_PLOT_TYPE, GogDoubleHistogramPlot))
+#define GOG_IS_DOUBLE_HISTOGRAM_PLOT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_DOUBLE_HISTOGRAM_PLOT_TYPE))
+
+GType gog_double_histogram_plot_get_type (void);
+
G_END_DECLS
#endif /* GOG_HISTOGRAM_H */
diff --git a/plugins/plot_distrib/plot-types.xml.in b/plugins/plot_distrib/plot-types.xml.in
index 008e8c4..cd6af3c 100644
--- a/plugins/plot_distrib/plot-types.xml.in
+++ b/plugins/plot_distrib/plot-types.xml.in
@@ -30,13 +30,32 @@
<property name="vertical">true</property>
<property name="guru-hints">backplane</property>
</Type>
- <Family _name="Histogram" sample_image_file="hist.xpm" axis_set="xy"/>
<Type _name="Histogram" row="3" col="1"
engine="GogHistogramPlot" family="Statistics"
_description="Histogram."
sample_image_file="chart_histogram_1_1.png">
<property name="guru-hints">backplane</property>
</Type>
+ <Type _name="CumulativeHistogram" row="3" col="2"
+ engine="GogHistogramPlot" family="Statistics"
+ _description="Cumulative histogram."
+ sample_image_file="chart_histogram_2_1.png">
+ <property name="guru-hints">backplane</property>
+ <property name="cumulative">true</property>
+ </Type>
+<!-- <Type _name="DoubleHistogram" row="3" col="3"
+ engine="GogDoubleHistogramPlot" family="Statistics"
+ _description="Double histogram."
+ sample_image_file="chart_histogram_1_3.png">
+ <property name="guru-hints">backplane</property>
+ </Type>
+ <Type _name="PopulationPyramid" row="3" col="4"
+ engine="GogDoubleHistogramPlot" family="Statistics"
+ _description="Population pyramid."
+ sample_image_file="chart_histogram_1_4.png">
+ <property name="guru-hints">backplane</property>
+ <property name="vertical">false</property>
+ </Type> -->
<Type _name="ProbabilityPlot" row="4" col="1"
engine="GogProbabilityPlot" family="Statistics"
_description="Probability plot."
diff --git a/plugins/plot_distrib/plugin.c b/plugins/plot_distrib/plugin.c
index edf3332..c062bba 100644
--- a/plugins/plot_distrib/plugin.c
+++ b/plugins/plot_distrib/plugin.c
@@ -28,6 +28,7 @@ GOFFICE_PLUGIN_MODULE_HEADER;
void gog_box_plot_register_type (GTypeModule *module);
void gog_box_plot_view_register_type (GTypeModule *module);
void gog_box_plot_series_register_type (GTypeModule *module);
+void gog_double_histogram_plot_register_type (GTypeModule *module);
void gog_histogram_plot_register_type (GTypeModule *module);
void gog_histogram_plot_series_register_type (GTypeModule *module);
void gog_histogram_plot_view_register_type (GTypeModule *module);
@@ -48,6 +49,7 @@ go_plugin_init (GOPlugin *plugin, GOCmdContext *cc)
gog_histogram_plot_view_register_type (module);
gog_histogram_plot_series_register_type (module);
gog_histogram_series_view_register_type (module);
+ gog_double_histogram_plot_register_type (module);
gog_probability_plot_register_type (module);
gog_probability_plot_view_register_type (module);
gog_probability_plot_series_register_type (module);
diff --git a/plugins/plot_distrib/plugin.xml.in b/plugins/plot_distrib/plugin.xml.in
index 38a3e2f..f1fb53f 100644
--- a/plugins/plot_distrib/plugin.xml.in
+++ b/plugins/plot_distrib/plugin.xml.in
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<plugin id="GOffice_plot_boxes">
+<plugin id="GOffice_plot_distrib">
<information>
<_name>Charting : distribution related plots</_name>
<_description>box-plots, histograms, and other distribution related plots</_description>
@@ -21,6 +21,11 @@
<_description>Histograms plotting engine</_description>
</information>
</service>
+<!-- <service type="plot_engine" id="GogDoubleHistogramPlot">
+ <information>
+ <_description>Double histograms plotting engine</_description>
+ </information>
+ </service> -->
<service type="plot_engine" id="GogProbabilityPlot">
<information>
<_description>Probability plots engine</_description>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]