[goffice] Add limits to the regression curve display range. [#669252]
- From: Jean BrÃfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Add limits to the regression curve display range. [#669252]
- Date: Fri, 10 Feb 2012 14:35:23 +0000 (UTC)
commit df77465105df27abfe3d70348e639a8ed2993f65
Author: Jean Brefort <jean brefort normalesup org>
Date: Fri Feb 10 15:34:22 2012 +0100
Add limits to the regression curve display range. [#669252]
ChangeLog | 15 +++
NEWS | 1 +
goffice/canvas/goc-group.h | 2 +-
goffice/graph/gog-reg-curve-prefs.ui | 168 ++++++++++++++++++++++----
goffice/graph/gog-reg-curve.c | 215 +++++++++++++++++++++++++++++++---
goffice/graph/gog-reg-curve.h | 12 ++-
goffice/utils/go-format.c | 54 +++++-----
goffice/utils/go-format.h | 4 +-
plugins/plot_distrib/gog-boxplot.c | 2 +-
plugins/reg_linear/gog-lin-reg.c | 5 +-
plugins/reg_linear/gog-polynom-reg.c | 16 +--
11 files changed, 407 insertions(+), 87 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ead3073..beed693 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2012-02-10 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/graph/gog-reg-curve-prefs.ui: add limits to the regression curve
+ display range. [#669252]
+ * goffice/graph/gog-reg-curve.c (limits_changed_cb),
+ (gog_reg_curve_populate_editor), (gog_reg_curve_get_property),
+ (gog_reg_curve_set_property), (gog_reg_curve_class_init),
+ (gog_reg_curve_init), (gog_reg_curve_dataset_dims),
+ (gog_reg_curve_dataset_get_elem), (gog_reg_curve_view_render): ditto.
+ * goffice/graph/gog-reg-curve.h: ditto.
+ * plugins/reg_linear/gog-lin-reg.c
+ (gog_lin_reg_curve_populate_editor): ditto.
+ * plugins/reg_linear/gog-polynom-reg.c
+ (gog_polynom_reg_curve_populate_editor): ditto.
+
2012-02-07 Jean Brefort <jean brefort normalesup org>
* goffice/graph/gog-renderer.c (gog_renderer_draw_gostring): take subscript
diff --git a/NEWS b/NEWS
index d388650..ce0fef2 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ Jean:
* Fixed graph type selector position. [#667793]
* Fix bounds for partial range logarithmic axes. [#669257]
* Fix Y-axis label position. [#669325]
+ * Add limits to the regression curve display range. [#669252]
Morten:
* Embed library ui files into library.
diff --git a/goffice/canvas/goc-group.h b/goffice/canvas/goc-group.h
index 15a1434..f786293 100644
--- a/goffice/canvas/goc-group.h
+++ b/goffice/canvas/goc-group.h
@@ -47,7 +47,7 @@ struct _GocGroupClass
void (*reserved2) (void);
void (*reserved3) (void);
void (*reserved4) (void);
-};
+};
#define GOC_TYPE_GROUP (goc_group_get_type ())
#define GOC_GROUP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOC_TYPE_GROUP, GocGroup))
diff --git a/goffice/graph/gog-reg-curve-prefs.ui b/goffice/graph/gog-reg-curve-prefs.ui
index 1e2e497..77408ed 100644
--- a/goffice/graph/gog-reg-curve-prefs.ui
+++ b/goffice/graph/gog-reg-curve-prefs.ui
@@ -1,78 +1,194 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
- <!-- interface-naming-policy toplevel-contextual -->
- <object class="GtkTable" id="reg-curve-prefs">
+ <object class="GtkGrid" id="reg-curve-prefs">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="border_width">12</property>
- <property name="n_rows">4</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">12</property>
<property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="name-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">(_Name):</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
<property name="xalign">0</property>
<property name="xpad">5</property>
<property name="label" translatable="yes">Low bound:</property>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
<property name="xalign">0</property>
<property name="xpad">5</property>
<property name="label" translatable="yes">High bound:</property>
</object>
<packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="skip-invalid">
<property name="label" translatable="yes">Skip invalid data</property>
+ <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
+ <property name="margin_left">12</property>
+ <property name="margin_bottom">6</property>
+ <property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
+ <property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ <property name="width">3</property>
+ <property name="height">1</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="name-label">
+ <object class="GtkLabel" id="label3">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">(_Name):</property>
- <property name="use_underline">True</property>
+ <property name="label" translatable="yes"><b>Used data</b></property>
+ <property name="use_markup">True</property>
</object>
<packing>
- <property name="y_options"></property>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">3</property>
+ <property name="height">1</property>
</packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><b>Drawing Limits:</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkComboBoxText" id="draw-limits-box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup" translatable="yes">None: the line will be displayed for the whole visible range.
+Absolute: the line will be displayed between the given limits.
+Relative: the line will be displayed between the data range expanded according to the values given below.</property>
+ <property name="tooltip_text" translatable="yes">None: the line will be displayed for the whole visible range.
+Absolute: the line will be displayed between the given limits.
+Relative: the line will be displayed between the data range expanded according to the values given below, with positive values enlarging the range.</property>
+ <items>
+ <item translatable="yes">None</item>
+ <item translatable="yes">Absolute</item>
+ <item translatable="yes">Relative</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="low-lbl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Low limit:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="high-lbl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">High limit:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="first-lbl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Low span:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkLabel" id="last-lbl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">High span:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
</child>
+
</object>
</interface>
diff --git a/goffice/graph/gog-reg-curve.c b/goffice/graph/gog-reg-curve.c
index a93f840..dce4e35 100644
--- a/goffice/graph/gog-reg-curve.c
+++ b/goffice/graph/gog-reg-curve.c
@@ -34,6 +34,7 @@ static GType gog_reg_curve_view_get_type (void);
enum {
REG_CURVE_PROP_0,
REG_CURVE_PROP_SKIP_INVALID,
+ REG_CURVE_PROP_DRAWING_BOUNDS
};
static void
@@ -45,12 +46,53 @@ gog_reg_curve_init_style (GogStyledObject *gso, GOStyle *style)
}
#ifdef GOFFICE_WITH_GTK
+
+struct reg_curve_closure {
+ GtkWidget *al1, *al2, *rl1, *rl2, *fe1, *fe2;
+ GObject *rc;
+};
+
static void
skip_invalid_toggled_cb (GtkToggleButton* btn, GObject *obj)
{
g_object_set (obj, "skip-invalid", gtk_toggle_button_get_active (btn), NULL);
}
+
+static void
+limits_changed_cb (GtkComboBox* btn, struct reg_curve_closure *cl)
+{
+ GogRegCurveDrawingBounds db = gtk_combo_box_get_active (btn);
+ switch (db) {
+ case GOG_REG_CURVE_DRAWING_BOUNDS_NONE:
+ gtk_widget_hide (cl->al1);
+ gtk_widget_hide (cl->al2);
+ gtk_widget_hide (cl->rl1);
+ gtk_widget_hide (cl->rl2);
+ gtk_widget_hide (cl->fe1);
+ gtk_widget_hide (cl->fe2);
+ break;
+ case GOG_REG_CURVE_DRAWING_BOUNDS_ABSOLUTE:
+ gtk_widget_show (cl->al1);
+ gtk_widget_show (cl->al2);
+ gtk_widget_hide (cl->rl1);
+ gtk_widget_hide (cl->rl2);
+ gtk_widget_show (cl->fe1);
+ gtk_widget_show (cl->fe2);
+ break;
+ case GOG_REG_CURVE_DRAWING_BOUNDS_RELATIVE:
+ gtk_widget_hide (cl->al1);
+ gtk_widget_hide (cl->al2);
+ gtk_widget_show (cl->rl1);
+ gtk_widget_show (cl->rl2);
+ gtk_widget_show (cl->fe1);
+ gtk_widget_show (cl->fe2);
+ break;
+ }
+ GOG_REG_CURVE (cl->rc)->drawing_bounds = db;
+ gog_object_emit_changed (GOG_OBJECT (cl->rc), FALSE);
+}
+
static void
gog_reg_curve_populate_editor (GogObject *gobj,
GOEditor *editor,
@@ -58,9 +100,11 @@ gog_reg_curve_populate_editor (GogObject *gobj,
GOCmdContext *cc)
{
GtkWidget *w;
- GtkTable *table;
+ GtkGrid *grid;
GtkBuilder *gui;
GogDataset *set = GOG_DATASET (gobj);
+ struct reg_curve_closure *cl;
+ GogRegCurveDrawingBounds db = GOG_REG_CURVE (gobj)->drawing_bounds;
gui = go_gtk_builder_new_internal ("res:go:graph/gog-reg-curve-prefs.ui", GETTEXT_PACKAGE, cc);
if (gui == NULL)
@@ -70,24 +114,59 @@ gog_reg_curve_populate_editor (GogObject *gobj,
go_gtk_builder_get_widget (gui, "reg-curve-prefs"),
_("Details"));
- table = GTK_TABLE (gtk_builder_get_object (gui, "reg-curve-prefs"));
+ cl = g_new0 (struct reg_curve_closure, 1);
+ cl->rc = G_OBJECT (gobj);
+ grid = GTK_GRID (gtk_builder_get_object (gui, "reg-curve-prefs"));
w = GTK_WIDGET (gog_data_allocator_editor (dalloc, set, -1, GOG_DATA_SCALAR));
gtk_widget_show (w);
- gtk_table_attach (table, w, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ gtk_grid_attach (grid, w, 1, 0, 2, 1);
w = GTK_WIDGET (gog_data_allocator_editor (dalloc, set, 0, GOG_DATA_SCALAR));
gtk_widget_show (w);
- gtk_table_attach (table, w, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ gtk_grid_attach (grid, w, 1, 2, 2, 1);
w = GTK_WIDGET (gog_data_allocator_editor (dalloc, set, 1, GOG_DATA_SCALAR));
gtk_widget_show (w);
- gtk_table_attach (table, w, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ gtk_grid_attach (grid, w, 1, 3, 2, 1);
w = go_gtk_builder_get_widget (gui, "skip-invalid");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w),
(GOG_REG_CURVE (gobj))->skip_invalid);
g_signal_connect (G_OBJECT (w), "toggled",
G_CALLBACK (skip_invalid_toggled_cb), gobj);
+ cl->fe1 = GTK_WIDGET (gog_data_allocator_editor (dalloc, set, 2, GOG_DATA_SCALAR));
+ gtk_grid_attach (grid, cl->fe1, 1, 6, 2, 1);
+ cl->fe2 = GTK_WIDGET (gog_data_allocator_editor (dalloc, set, 3, GOG_DATA_SCALAR));
+ gtk_grid_attach (grid, cl->fe2, 1, 7, 2, 1);
+ cl->al1 = go_gtk_builder_get_widget (gui, "low-lbl");
+ cl->al2 = go_gtk_builder_get_widget (gui, "high-lbl");
+ cl->rl1 = go_gtk_builder_get_widget (gui, "first-lbl");
+ cl->rl2 = go_gtk_builder_get_widget (gui, "last-lbl");
+ switch (db) {
+ case GOG_REG_CURVE_DRAWING_BOUNDS_NONE:
+ gtk_widget_hide (cl->al1);
+ gtk_widget_hide (cl->al2);
+ gtk_widget_hide (cl->rl1);
+ gtk_widget_hide (cl->rl2);
+ break;
+ case GOG_REG_CURVE_DRAWING_BOUNDS_ABSOLUTE:
+ gtk_widget_hide (cl->rl1);
+ gtk_widget_hide (cl->rl2);
+ gtk_widget_show (cl->fe1);
+ gtk_widget_show (cl->fe2);
+ break;
+ case GOG_REG_CURVE_DRAWING_BOUNDS_RELATIVE:
+ gtk_widget_hide (cl->al1);
+ gtk_widget_hide (cl->al2);
+ gtk_widget_show (cl->fe1);
+ gtk_widget_show (cl->fe2);
+ break;
+ }
+ w = go_gtk_builder_get_widget (gui, "draw-limits-box");
+ gtk_combo_box_set_active (GTK_COMBO_BOX (w), db);
+ g_signal_connect (G_OBJECT (w), "changed",
+ G_CALLBACK (limits_changed_cb), cl);
if ((GOG_REG_CURVE_GET_CLASS (gobj))->populate_editor != NULL)
- (GOG_REG_CURVE_GET_CLASS (gobj))->populate_editor (GOG_REG_CURVE (gobj), table);
+ (GOG_REG_CURVE_GET_CLASS (gobj))->populate_editor (GOG_REG_CURVE (gobj), grid);
+ g_object_set_data_full (G_OBJECT (grid), "rc-closure", cl, g_free);
g_object_unref (gui);
(GOG_OBJECT_CLASS (reg_curve_parent_klass)->populate_editor) (gobj, editor, dalloc, cc);
@@ -103,10 +182,24 @@ gog_reg_curve_get_property (GObject *obj, guint param_id,
case REG_CURVE_PROP_SKIP_INVALID:
g_value_set_boolean (value, rc->skip_invalid);
break;
+ case REG_CURVE_PROP_DRAWING_BOUNDS:
+ switch (rc->drawing_bounds) {
+ case GOG_REG_CURVE_DRAWING_BOUNDS_NONE:
+ g_value_set_string (value, "none");
+ break;
+ case GOG_REG_CURVE_DRAWING_BOUNDS_ABSOLUTE:
+ g_value_set_string (value, "absolute");
+ break;
+ case GOG_REG_CURVE_DRAWING_BOUNDS_RELATIVE:
+ g_value_set_string (value, "relative");
+ break;
+ }
+ break;
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
break;
}
+ gog_object_emit_changed (GOG_OBJECT (rc), FALSE);
}
static void
@@ -119,6 +212,17 @@ gog_reg_curve_set_property (GObject *obj, guint param_id,
rc->skip_invalid = g_value_get_boolean (value);
gog_object_request_update (GOG_OBJECT (obj));
break;
+ case REG_CURVE_PROP_DRAWING_BOUNDS: {
+ char const *str = g_value_get_string (value);
+ if (!strcmp (str, "absolute"))
+ rc->drawing_bounds = GOG_REG_CURVE_DRAWING_BOUNDS_ABSOLUTE;
+ else if (!strcmp (str, "relative"))
+ rc->drawing_bounds = GOG_REG_CURVE_DRAWING_BOUNDS_RELATIVE;
+ else
+ rc->drawing_bounds = GOG_REG_CURVE_DRAWING_BOUNDS_NONE;
+ gog_object_emit_changed (GOG_OBJECT (rc), FALSE);
+ break;
+ }
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
return; /* NOTE : RETURN */
@@ -183,27 +287,33 @@ gog_reg_curve_class_init (GogObjectClass *gog_klass)
_("Skip invalid data"),
FALSE,
GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+ g_object_class_install_property (gobject_klass, REG_CURVE_PROP_DRAWING_BOUNDS,
+ g_param_spec_string ("drawing-bounds",
+ _("Drawing bounds"),
+ _("How the regression line should be limited, acceptable values are \"none\", \"absolute\", and \"relative\"."),
+ "none",
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
}
static void
gog_reg_curve_init (GogRegCurve *reg_curve)
{
reg_curve->ninterp = 100;
- reg_curve->bounds = g_new0 (GogDatasetElement,3) + 1;
+ reg_curve->bounds = g_new0 (GogDatasetElement,5) + 1;
}
static void
gog_reg_curve_dataset_dims (GogDataset const *set, int *first, int *last)
{
*first = -1;
- *last = 1;
+ *last = 3;
}
static GogDatasetElement *
gog_reg_curve_dataset_get_elem (GogDataset const *set, int dim_i)
{
GogRegCurve const *rc = GOG_REG_CURVE (set);
- g_return_val_if_fail (2 > dim_i, NULL);
+ g_return_val_if_fail (4 > dim_i, NULL);
g_return_val_if_fail (dim_i >= -1, NULL);
return rc->bounds + dim_i;
}
@@ -287,7 +397,7 @@ gog_reg_curve_view_render (GogView *view, GogViewAllocation const *bbox)
GogSeries *series = GOG_SERIES ((GOG_OBJECT (rc))->parent);
GogPlot *plot = series->plot;
GogChart *chart = GOG_CHART (GOG_OBJECT (plot)->parent);
- GogAxisMap *x_map, *y_map;
+ GogAxisMap *x_map;
GogChartMap *chart_map;
GOStyle *style;
GOPath *path;
@@ -306,17 +416,92 @@ gog_reg_curve_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);
gog_renderer_push_clip_rectangle (view->renderer, view->residual.x, view->residual.y,
view->residual.w, view->residual.h);
x = g_new (double, rc->ninterp + 1);
y = g_new (double, rc->ninterp + 1);
- delta_x = view->residual.w / rc->ninterp;
- for (i = 0; i <= rc->ninterp; i++) {
- x[i] = gog_axis_map_from_view (x_map, i * delta_x + view->residual.x);
- y[i] = gog_reg_curve_get_value_at (rc, x[i]);
+ switch (rc->drawing_bounds) {
+ case GOG_REG_CURVE_DRAWING_BOUNDS_NONE:
+ delta_x = view->residual.w / rc->ninterp;
+ for (i = 0; i <= rc->ninterp; i++) {
+ x[i] = gog_axis_map_from_view (x_map, i * delta_x + view->residual.x);
+ y[i] = gog_reg_curve_get_value_at (rc, x[i]);
+ }
+ break;
+ case GOG_REG_CURVE_DRAWING_BOUNDS_ABSOLUTE: {
+ double min, max;
+ if (rc->bounds[2].data) {
+ min = go_data_get_scalar_value (rc->bounds[2].data);
+ if (min == go_nan || !go_finite (min))
+ min = gog_axis_map_from_view (x_map, view->residual.x);
+
+ } else
+ min = gog_axis_map_from_view (x_map, view->residual.x);
+ if (rc->bounds[3].data) {
+ max = go_data_get_scalar_value (rc->bounds[3].data);
+ if (max == go_nan || !go_finite (max))
+ max = gog_axis_map_from_view (x_map, view->residual.x + view->residual.w);
+
+ } else
+ max = gog_axis_map_from_view (x_map, view->residual.x + view->residual.w);
+
+ delta_x = (max - min) / rc->ninterp;
+ for (i = 0; i <= rc->ninterp; i++) {
+ x[i] = min + i * delta_x;
+ y[i] = gog_reg_curve_get_value_at (rc, x[i]);
+ }
+ break;
+ }
+ case GOG_REG_CURVE_DRAWING_BOUNDS_RELATIVE: {
+ double min, max, val;
+ GOData *data = NULL;
+ GogSeries *series = GOG_SERIES (gog_object_get_parent (GOG_OBJECT (rc)));
+ GogSeriesDesc *desc = &GOG_PLOT_GET_CLASS (series->plot)->desc.series;
+ int i;
+ /* first, look for the index values */
+ for (i = 0; i < (int) desc->num_dim; i++)
+ if (desc->dim[i].val_type == GOG_DIM_INDEX) {
+ data = series->values[i].data;
+ break;
+ }
+ if (data)
+ go_data_get_bounds (data, &min, &max);
+ else {
+ min = 0.;
+ max = series->num_elements - 1;
+ }
+ if (rc->bounds[0].data) {
+ val = go_data_get_scalar_value (rc->bounds[0].data);
+ if (val != go_nan && go_finite (val))
+ min = val;
+ }
+ if (rc->bounds[1].data) {
+ val = go_data_get_scalar_value (rc->bounds[1].data);
+ if (val != go_nan && go_finite (val))
+ max = val;
+ }
+ if (rc->bounds[2].data) {
+ val = go_data_get_scalar_value (rc->bounds[2].data);
+ if (val != go_nan && go_finite (val))
+ min -= val;
+
+ }
+ if (rc->bounds[3].data) {
+ val = go_data_get_scalar_value (rc->bounds[3].data);
+ if (val != go_nan && go_finite (val))
+ max += val;
+
+ }
+
+ delta_x = (max - min) / rc->ninterp;
+ for (i = 0; i <= rc->ninterp; i++) {
+ x[i] = min + i * delta_x;
+ y[i] = gog_reg_curve_get_value_at (rc, x[i]);
+ }
+ break;
+ }
}
path = gog_chart_map_make_path (chart_map, x, y, rc->ninterp + 1, GO_LINE_INTERPOLATION_CUBIC_SPLINE, FALSE, NULL);
diff --git a/goffice/graph/gog-reg-curve.h b/goffice/graph/gog-reg-curve.h
index 7e3061c..5fed398 100644
--- a/goffice/graph/gog-reg-curve.h
+++ b/goffice/graph/gog-reg-curve.h
@@ -26,18 +26,24 @@
G_BEGIN_DECLS
+typedef enum {
+ GOG_REG_CURVE_DRAWING_BOUNDS_NONE,
+ GOG_REG_CURVE_DRAWING_BOUNDS_ABSOLUTE,
+ GOG_REG_CURVE_DRAWING_BOUNDS_RELATIVE
+} GogRegCurveDrawingBounds;
+
struct _GogRegCurve {
GogTrendLine base;
- GogSeries *series;
gboolean weighted;
- GODataVector *weights;
GogDatasetElement *bounds; /* aliased to include the name as -1 */
gboolean skip_invalid; /* do not take into account invalid data */
int ninterp; /* how many points to use for display the curve as a vpath */
double *a; /* calculated coefficients, must be allocated by derived class */
double R2; /* squared regression coefficient */
char *equation;
+ GogRegCurveDrawingBounds drawing_bounds;
+ gpointer priv;
};
typedef struct {
@@ -46,6 +52,8 @@ typedef struct {
double (*get_value_at) (GogRegCurve *reg_curve, double x);
char const * (*get_equation) (GogRegCurve *reg_curve);
void (*populate_editor) (GogRegCurve *reg_curve, gpointer table);
+ void (*reserved1) (void);
+ void (*reserved2) (void);
} GogRegCurveClass;
#define GOG_TYPE_REG_CURVE (gog_reg_curve_get_type ())
diff --git a/goffice/utils/go-format.c b/goffice/utils/go-format.c
index 9d222f2..0f55cc9 100644
--- a/goffice/utils/go-format.c
+++ b/goffice/utils/go-format.c
@@ -302,7 +302,7 @@ typedef enum {
GO_FMT_SHAPE_SIGNS = 1,
/* GENERAL implies GO_FMT_POSITION_MARKERS whether this is set or not */
/* This is only useful for Chinese/Japanese/Korean numerals */
- GO_FMT_POSITION_MARKERS = 2
+ GO_FMT_POSITION_MARKERS = 2
} GOFormatShapeFlags;
typedef struct {
@@ -703,7 +703,7 @@ go_format_parse_locale (const char *str, GOFormatLocale *locale, gsize *nchars)
if (*str == '-') {
str++;
ull = g_ascii_strtoull (str, &end, 16);
- if (str == end || errno == ERANGE ||
+ if (str == end || errno == ERANGE ||
ull > G_GINT64_CONSTANT(0x0001ffffffffffffU))
return FALSE;
} else {
@@ -1276,19 +1276,19 @@ handle_common_token (const char *tstr, GOFormatToken t, GString *prg)
char *lname = NULL;
oldlocale = g_strdup (setlocale (LC_ALL, NULL));
ok = setlocale (LC_ALL, lang) != NULL;
-
+
if (!ok) {
lname = g_strdup_printf ("%s.utf-8",lang);
lang = lname;
ok = setlocale (LC_ALL, lang) != NULL;
}
-
+
setlocale (LC_ALL, oldlocale);
g_free (oldlocale);
-
+
if (ok) {
ADD_OP (OP_LOCALE);
- g_string_append_len (prg, (void *)&locale,
+ g_string_append_len (prg, (void *)&locale,
sizeof (locale));
/* Include the terminating zero: */
g_string_append_len (prg, lang, strlen (lang) + 1);
@@ -2396,8 +2396,8 @@ go_format_dump_program (const guchar *prg)
prg += sizeof (locale);
lang = (const char *)prg;
prg += strlen (lang) + 1;
- g_printerr ("OP_LOCALE -- \"%s\" -- numeral shape: %#x -- calendar: %#x\n",
- lang,
+ g_printerr ("OP_LOCALE -- \"%s\" -- numeral shape: %#x -- calendar: %#x\n",
+ lang,
(guint)((locale.locale & 0xFFF000000) >> 24),
(guint)((locale.locale & 0x000FF0000) >> 16));
break;
@@ -2870,7 +2870,7 @@ static char const *minus_shapes[] =
UTF8_FULLWIDTH_MINUS, /* 24 Korean 1 ? */
UTF8_FULLWIDTH_MINUS, /* 25 Korean 2 ? */
UTF8_FULLWIDTH_MINUS, /* 26 Korean 3 ? */
- UTF8_FULLWIDTH_MINUS, /* 27 Korean 4 ? */
+ UTF8_FULLWIDTH_MINUS, /* 27 Korean 4 ? */
};
static char const *plus_shapes[] =
@@ -2914,14 +2914,14 @@ static char const *plus_shapes[] =
UTF8_FULLWIDTH_PLUS, /* 24 Korean 1 ? */
UTF8_FULLWIDTH_PLUS, /* 25 Korean 2 ? */
UTF8_FULLWIDTH_PLUS, /* 26 Korean 3 ? */
- UTF8_FULLWIDTH_PLUS, /* 27 Korean 4 ? */
+ UTF8_FULLWIDTH_PLUS, /* 27 Korean 4 ? */
};
#endif
#ifdef DEFINE_COMMON
-static char const *numeral_shapes[][10]
+static char const *numeral_shapes[][10]
= {{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, /* 00 Unused */
{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, /* 01 Unused */
{"\331\240","\331\241","\331\242","\331\243","\331\244","\331\245","\331\246",
@@ -3319,7 +3319,7 @@ convert_numerals (GString *str, gsize from, gsize to, guint shape)
go_string_replace (str, i, 1, num_str, -1);
val = TRUE;
}
- } else if (shape == 0x11 &&
+ } else if (shape == 0x11 &&
str->str[i] >= 'a' &&
str->str[i] <= 'k') {
gint num = str->str[i] - 'a';
@@ -3327,7 +3327,7 @@ convert_numerals (GString *str, gsize from, gsize to, guint shape)
if (*num_str != 0) {
go_string_replace (str, i, 1, num_str, -1);
val = TRUE;
- }
+ }
}
}
return val;
@@ -3353,8 +3353,8 @@ convert_sign (GString *str, size_t i, guint shape, guint shape_flags)
return FALSE;
}
- if (((shape_flags & GO_FMT_SHAPE_SIGNS) == 0) ||
- (shape <= 1) ||
+ if (((shape_flags & GO_FMT_SHAPE_SIGNS) == 0) ||
+ (shape <= 1) ||
(shape > G_N_ELEMENTS (minus_shapes)))
shaped_sign = sign;
else
@@ -3366,7 +3366,7 @@ convert_sign (GString *str, size_t i, guint shape, guint shape_flags)
}
static void
-handle_ethiopic (GString *numtxt, const char **dot, guint numeral_shape,
+handle_ethiopic (GString *numtxt, const char **dot, guint numeral_shape,
guint shape_flags)
{
gint last;
@@ -3374,7 +3374,7 @@ handle_ethiopic (GString *numtxt, const char **dot, guint numeral_shape,
gboolean cnt = 0;
gint tail = 0;
- if ((shape_flags & GO_FMT_POSITION_MARKERS) == 0 ||
+ if ((shape_flags & GO_FMT_POSITION_MARKERS) == 0 ||
numeral_shape != 0x11)
return;
if (dot && *dot) {
@@ -3409,7 +3409,7 @@ handle_ethiopic (GString *numtxt, const char **dot, guint numeral_shape,
} else {
numtxt->str[last] += ('a'-'1');
if (numtxt->str[last + 1] == '0')
- g_string_erase (numtxt, last + 1, 1);
+ g_string_erase (numtxt, last + 1, 1);
}
}
hundred = !hundred;
@@ -3434,7 +3434,7 @@ handle_ethiopic (GString *numtxt, const char **dot, guint numeral_shape,
static void
-handle_chinese (GString *numtxt, const char **dot, guint numeral_shape,
+handle_chinese (GString *numtxt, const char **dot, guint numeral_shape,
guint shape_flags)
{
GString *ntxt;
@@ -3443,7 +3443,7 @@ handle_chinese (GString *numtxt, const char **dot, guint numeral_shape,
gboolean wan_written = TRUE;
gboolean digit_written = FALSE;
gboolean suppress_ten, suppress_ten_always;
- if ((shape_flags & GO_FMT_POSITION_MARKERS) == 0 ||
+ if ((shape_flags & GO_FMT_POSITION_MARKERS) == 0 ||
numeral_shape < 0x1B || numeral_shape > 0x27)
return;
last = ((dot && *dot) ? *dot - 1 : numtxt->str + (numtxt->len - 1));
@@ -3451,7 +3451,7 @@ handle_chinese (GString *numtxt, const char **dot, guint numeral_shape,
return;
ntxt = g_string_sized_new (100);
- suppress_ten = (numeral_shape == 0x1b || numeral_shape == 0x1d
+ suppress_ten = (numeral_shape == 0x1b || numeral_shape == 0x1d
|| numeral_shape == 0x26);
suppress_ten_always = (numeral_shape == 0x26);
i = 0;
@@ -3469,7 +3469,7 @@ handle_chinese (GString *numtxt, const char **dot, guint numeral_shape,
if (i > 0)
g_string_prepend_c (ntxt, 'a' + i - 1);
if (!suppress_ten_always ||
- !(suppress_ten && wan == 0) ||
+ !(suppress_ten && wan == 0) ||
*last != '1')
g_string_prepend_c (ntxt, *last);
digit_written = TRUE;
@@ -3976,9 +3976,9 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
numtxt = g_string_sized_new (100);
g_string_printf (numtxt, "%.*" FORMAT_f, n, val);
dot = strstr (numtxt->str, decimal->str);
- handle_chinese (numtxt, &dot,
+ handle_chinese (numtxt, &dot,
numeral_shape, shape_flags);
- handle_ethiopic (numtxt, &dot,
+ handle_ethiopic (numtxt, &dot,
numeral_shape, shape_flags);
if (dot) {
size_t i = numtxt->len;
@@ -4125,7 +4125,7 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
}
g_string_append_c (dst, c);
if ((numeral_shape) > 1) /* 0: not set; 1: Western */
- convert_numerals (dst, dst->len - 1, dst->len - 1,
+ convert_numerals (dst, dst->len - 1, dst->len - 1,
numeral_shape);
break;
}
@@ -4199,7 +4199,7 @@ SUFFIX(go_format_execute) (PangoLayout *layout, GString *dst,
/* FIXME: we need to fix the exponent handling */
/* until that time use only latin numerals */
numeral_shape = 0;
-
+
markup_stack = g_slist_prepend
(markup_stack, GSIZE_TO_POINTER (dst->len));
}
@@ -4562,7 +4562,7 @@ go_format_measure_strlen (const GString *str,
convert_numerals (str, 0, str->len - 1, num_shape); \
} \
} while (0)
-
+
/*
* go_format_general:
* @layout: Optional PangoLayout, probably preseeded with font attribute.
diff --git a/goffice/utils/go-format.h b/goffice/utils/go-format.h
index 08780d7..f6a6220 100644
--- a/goffice/utils/go-format.h
+++ b/goffice/utils/go-format.h
@@ -136,7 +136,7 @@ void go_render_general (PangoLayout *layout, GString *str,
const GOFontMetrics *metrics,
double val,
int col_width,
- gboolean unicode_minus,
+ gboolean unicode_minus,
guint numeral_shape,
guint custom_shape_flags);
#ifdef GOFFICE_WITH_LONG_DOUBLE
@@ -145,7 +145,7 @@ void go_render_generall (PangoLayout *layout, GString *str,
const GOFontMetrics *metrics,
long double val,
int col_width,
- gboolean unicode_minus,
+ gboolean unicode_minus,
guint numeral_shape,
guint custom_shape_flags);
#endif
diff --git a/plugins/plot_distrib/gog-boxplot.c b/plugins/plot_distrib/gog-boxplot.c
index d8157ed..5f0c88a 100644
--- a/plugins/plot_distrib/gog-boxplot.c
+++ b/plugins/plot_distrib/gog-boxplot.c
@@ -109,7 +109,7 @@ display_before_grid_cb (GtkToggleButton *btn, GObject *obj)
static gpointer
gog_box_plot_pref (GogObject *obj,
GogDataAllocator *dalloc, GOCmdContext *cc)
-{
+{
GogBoxPlot *boxplot = GOG_BOX_PLOT (obj);
GtkBuilder *gui =
go_gtk_builder_new ("res:go:plot_distrib/gog-boxplot-prefs.ui",
diff --git a/plugins/reg_linear/gog-lin-reg.c b/plugins/reg_linear/gog-lin-reg.c
index b78c97b..f855531 100644
--- a/plugins/reg_linear/gog-lin-reg.c
+++ b/plugins/reg_linear/gog-lin-reg.c
@@ -150,16 +150,13 @@ affine_toggled_cb (GtkToggleButton *btn, GObject *obj)
static void
gog_lin_reg_curve_populate_editor (GogRegCurve *reg_curve, gpointer table)
{
- int rows, columns;
GtkWidget *w;
GogLinRegCurve *lin = GOG_LIN_REG_CURVE (reg_curve);
- g_object_get (G_OBJECT (table), "n-rows", &rows, "n-columns", &columns, NULL);
- gtk_table_resize (table, rows + 1, columns);
w = gtk_check_button_new_with_label (_("Affine"));
gtk_widget_set_tooltip_text (w, _("Uncheck to force zero intercept"));
gtk_widget_show (w);
- gtk_table_attach (table, w, 0, columns, rows, rows + 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ gtk_grid_attach_next_to (table, w, NULL, GTK_POS_BOTTOM, 1, 3);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), lin->affine);
g_signal_connect (G_OBJECT (w), "toggled", G_CALLBACK (affine_toggled_cb), lin);
}
diff --git a/plugins/reg_linear/gog-polynom-reg.c b/plugins/reg_linear/gog-polynom-reg.c
index 6209832..f9c683a 100644
--- a/plugins/reg_linear/gog-polynom-reg.c
+++ b/plugins/reg_linear/gog-polynom-reg.c
@@ -193,21 +193,19 @@ order_changed_cb (GtkSpinButton *btn, GObject *obj)
static void
gog_polynom_reg_curve_populate_editor (GogRegCurve *reg_curve, gpointer table)
{
- int rows, columns;
- GtkWidget *w;
+ GtkWidget *l, *w;
GogLinRegCurve *lin = GOG_LIN_REG_CURVE (reg_curve);
((GogRegCurveClass*) gog_polynom_reg_curve_parent_klass)->populate_editor (reg_curve, table);
- g_object_get (G_OBJECT (table), "n-rows", &rows, "n-columns", &columns, NULL);
- gtk_table_resize (table, rows + 1, columns);
- w = gtk_label_new (_("Order:"));
- gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_LEFT);
- gtk_widget_show (w);
- gtk_table_attach (table, w, 0, 1, rows, rows + 1, 0, 0, 0, 0);
+ l = gtk_label_new (_("Order:"));
+ gtk_misc_set_alignment (GTK_MISC (l), 0., 0.5);
+ gtk_label_set_justify (GTK_LABEL (l), GTK_JUSTIFY_LEFT);
+ gtk_widget_show (l);
+ gtk_grid_attach_next_to (table, l, NULL, GTK_POS_BOTTOM, 1, 1);
w = gtk_spin_button_new_with_range (2, 10, 1);
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (w), 0);
gtk_widget_show (w);
- gtk_table_attach (table, w, 1, columns, rows, rows + 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+ gtk_grid_attach_next_to (table, w, l, GTK_POS_RIGHT, 1, 1);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), lin->dims);
g_signal_connect (G_OBJECT (w), "value-changed", G_CALLBACK (order_changed_cb), lin);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]