goffice r2279 - in trunk: . goffice/graph goffice/utils plugins/plot_xy



Author: jbrefort
Date: Mon Nov 24 07:45:24 2008
New Revision: 2279
URL: http://svn.gnome.org/viewvc/goffice?rev=2279&view=rev

Log:
2008-11-24  Jean Brefort  <jean brefort normalesup org>

	* goffice/graph/gog-axis.c: add support for clamped splines.
	* goffice/graph/gog-axis.h: ditto.
	* goffice/graph/gog-chart-map.c: ditto.
	* goffice/graph/gog-chart-map.h: ditto.
	* goffice/graph/gog-series-impl.h: ditto.
	* goffice/graph/gog-series-prefs.glade: ditto.
	* goffice/graph/gog-series.c: ditto.
	* goffice/graph/gog-series.h: ditto.
	* goffice/utils/go-line.c: ditto.
	* goffice/utils/go-line.h: ditto.
	* plugins/plot_xy/gog-xy.c: ditto.
	* plugins/plot_xy/gog-xy.h: ditto.



Modified:
   trunk/ChangeLog
   trunk/goffice/graph/gog-axis.c
   trunk/goffice/graph/gog-axis.h
   trunk/goffice/graph/gog-chart-map.c
   trunk/goffice/graph/gog-chart-map.h
   trunk/goffice/graph/gog-series-impl.h
   trunk/goffice/graph/gog-series-prefs.glade
   trunk/goffice/graph/gog-series.c
   trunk/goffice/graph/gog-series.h
   trunk/goffice/utils/go-line.c
   trunk/goffice/utils/go-line.h
   trunk/plugins/plot_xy/gog-xy.c
   trunk/plugins/plot_xy/gog-xy.h

Modified: trunk/goffice/graph/gog-axis.c
==============================================================================
--- trunk/goffice/graph/gog-axis.c	(original)
+++ trunk/goffice/graph/gog-axis.c	Mon Nov 24 07:45:24 2008
@@ -149,6 +149,7 @@
 struct _GogAxisMapDesc {
 	double 		(*map) 		 (GogAxisMap *map, double value);
 	double 		(*map_to_view)   (GogAxisMap *map, double value);
+	double 		(*map_derivative_to_view)   (GogAxisMap *map, double value);
 	double 		(*map_from_view) (GogAxisMap *map, double value);
 	gboolean	(*map_finite)    (double value);
 	double		(*map_baseline)  (GogAxisMap *map);
@@ -217,6 +218,16 @@
 }
 
 static double
+map_discrete_derivative_to_view (GogAxisMap *map, double value)
+{
+	/* WARNING: does this makes sense? */
+	MapData *data = map->data;
+
+	return map->axis->inverted ? -data->a: data->a;
+
+}
+
+static double
 map_discrete_from_view (GogAxisMap *map, double value)
 {
 	MapData *data = map->data;
@@ -352,6 +363,15 @@
 }
 
 static double
+map_linear_derivative_to_view (GogAxisMap *map, double value)
+{
+	MapData *data = map->data;
+
+	return map->axis->inverted ? -data->a: data->a;
+
+}
+
+static double
 map_linear_from_view (GogAxisMap *map, double value)
 {
 	MapData *data = map->data;
@@ -572,6 +592,18 @@
 }
 
 static double
+map_log_derivative_to_view (GogAxisMap *map, double value)
+{
+	MapLogData *data = map->data;
+
+	if (value <= 0.)
+		return go_nan;
+	return map->axis->inverted ? data->a_inv / value:
+		data->a / value;
+
+}
+
+static double
 map_log_from_view (GogAxisMap *map, double value)
 {
 	MapLogData *data = map->data;
@@ -704,7 +736,7 @@
 
 static const GogAxisMapDesc map_desc_discrete = 
 {
-	map_discrete,			map_discrete_to_view,
+	map_discrete,			map_discrete_to_view,   map_discrete_derivative_to_view,
 	map_discrete_from_view,		go_finite,
 	map_baseline,			map_bounds,
 	map_discrete_init,		NULL,
@@ -715,7 +747,7 @@
 static const GogAxisMapDesc map_descs[] = 
 {
 	{
-		map_linear,		map_linear_to_view,
+		map_linear,		map_linear_to_view,     map_linear_derivative_to_view,
 		map_linear_from_view,   go_finite,
 		map_baseline,		map_bounds,
 		map_linear_init, 	NULL,	
@@ -723,7 +755,7 @@
 		N_("Linear"),		N_("Linear mapping")
 	},
 	{
-		map_log,		map_log_to_view,
+		map_log,		map_log_to_view,	map_log_derivative_to_view,
 		map_log_from_view,	map_log_finite,
 		map_log_baseline,	map_log_bounds,
 		map_log_init,		NULL,	
@@ -883,6 +915,21 @@
 }
 
 /**
+ * gog_axis_map_to_view :
+ * @map : a #GogAxisMap
+ * @value : value to map to canvas space
+ *
+ * Returns: the derivative of the mapping expression at value.
+ **/
+
+double 
+gog_axis_map_derivative_to_view (GogAxisMap *map,
+		      double value)
+{
+	return map->desc->map_derivative_to_view (map, value);
+}
+
+/**
  * gog_axis_map_finite :
  * @map : a #GogAxisMap
  * @value : value to test

Modified: trunk/goffice/graph/gog-axis.h
==============================================================================
--- trunk/goffice/graph/gog-axis.h	(original)
+++ trunk/goffice/graph/gog-axis.h	Mon Nov 24 07:45:24 2008
@@ -56,6 +56,7 @@
 GogAxisMap*   gog_axis_map_new	 	  (GogAxis *axis, double offset, double length);
 double	      gog_axis_map 		  (GogAxisMap *map, double value);
 double	      gog_axis_map_to_view	  (GogAxisMap *map, double value);
+double	      gog_axis_map_derivative_to_view (GogAxisMap *map, double value);
 double	      gog_axis_map_from_view	  (GogAxisMap *map, double value);
 gboolean      gog_axis_map_finite	  (GogAxisMap *map, double value);
 double	      gog_axis_map_get_baseline	  (GogAxisMap *map);

Modified: trunk/goffice/graph/gog-chart-map.c
==============================================================================
--- trunk/goffice/graph/gog-chart-map.c	(original)
+++ trunk/goffice/graph/gog-chart-map.c	Mon Nov 24 07:45:24 2008
@@ -36,6 +36,7 @@
 	gboolean		 is_valid;
 
 	void 	 (*map_2D_to_view) 	(GogChartMap *map, double x, double y, double *u, double *v);
+	double 	 (*map_2D_derivative_to_view) (GogChartMap *map, double deriv, double x, double y);
 	GOPath  *(*make_path)	   	(GogChartMap *map, double const *x, double const *y, int n_points,
 					 GOLineInterpolation interpolation, gboolean skip_invalid, gpointer data);
 	GOPath  *(*make_close_path)	(GogChartMap *map, double const *x, double const *y, int n_points,
@@ -184,6 +185,18 @@
 	*v = gog_axis_map_to_view (map->axis_map[1], y);
 }
 
+static double
+xy_map_2D_derivative_to_view (GogChartMap *map, double deriv, double x, double y)
+{
+	double d;
+	d = gog_axis_map_derivative_to_view (map->axis_map[0], x);
+	if (isnan (d))
+		return go_nan;
+	deriv /= d;
+	d = gog_axis_map_derivative_to_view (map->axis_map[1], y);
+	return (isnan (d))? go_nan: deriv * d;
+}
+
 static GOPath *
 make_path_linear (GogChartMap *map,
 		  double const *x, double const *y,
@@ -327,8 +340,12 @@
 	n_valid_points = 0;
 
 	if (type == GO_CSPLINE_CLAMPED && data != NULL) {
-		p0 = ((double*) data)[0];
-		p1 = ((double*) data)[1];
+		p0 = gog_chart_map_2D_derivative_to_view (map, ((double*) data)[0],
+							  x != NULL ? x[i] : i + 1,
+							  y != NULL ? y[i] : i + 1);
+		p1 = gog_chart_map_2D_derivative_to_view (map, ((double*) data)[1],
+							  x != NULL ? x[i] : i + 1,
+							  y != NULL ? y[i] : i + 1);
 	} else
 		p0 = p1 = 0.;
 
@@ -484,9 +501,9 @@
 		case GO_LINE_INTERPOLATION_CUBIC_CUBIC_SPLINE:
 			path = make_path_cspline (map, x, y, n_points, TRUE, GO_CSPLINE_CUBIC, skip_invalid, data);
 			break;
-/*		case GO_LINE_INTERPOLATION_CLAMPED_CUBIC_SPLINE:
+		case GO_LINE_INTERPOLATION_CLAMPED_CUBIC_SPLINE:
 			path = make_path_cspline (map, x, y, n_points, TRUE, GO_CSPLINE_CLAMPED, skip_invalid, data);
-			break;*/
+			break;
 		case GO_LINE_INTERPOLATION_STEP_START:
 		case GO_LINE_INTERPOLATION_STEP_END:
 		case GO_LINE_INTERPOLATION_STEP_CENTER_X:
@@ -799,6 +816,7 @@
 				data->a = - area->h;
 
 				map->map_2D_to_view = x_map_2D_to_view;
+				map->map_2D_derivative_to_view = NULL;
 				map->make_path = NULL;
 				map->make_close_path = NULL;
 				map->data = data;
@@ -816,6 +834,7 @@
 
 				map->data = NULL;
 				map->map_2D_to_view = xy_map_2D_to_view;
+				map->map_2D_derivative_to_view = xy_map_2D_derivative_to_view;
 				map->make_path = xy_make_path;
 				map->make_close_path = xy_make_close_path;
 
@@ -855,6 +874,7 @@
 
 				map->data = data;
 				map->map_2D_to_view = polar_map_2D_to_view;
+				map->map_2D_derivative_to_view = NULL;
 				map->make_path = polar_make_path;
 				map->make_close_path = polar_make_close_path;
 
@@ -865,6 +885,7 @@
 		default:
 			g_warning ("[GogChartMap::new] unimplemented for axis set %d", axis_set);
 			map->map_2D_to_view = null_map_2D;
+			map->map_2D_derivative_to_view = NULL;
 			break;
 	}
 
@@ -888,6 +909,26 @@
 	(map->map_2D_to_view) (map, x, y, u, v);
 }
 
+
+/**
+ * gog_chart_map_2D_to_view:
+ * @map: a #GogChartMap
+ * @deriv: the slope in data space
+ * @x: data x value
+ * @y: data y value
+ *
+ * Converts a 2D slope from data space to canvas space. It is only implemented
+ for xy maps.
+ * Returns: the slope in canvas space or go_nan.
+ **/
+
+double
+gog_chart_map_2D_derivative_to_view (GogChartMap *map, double deriv, double x, double y)
+{
+	return (map->map_2D_derivative_to_view)?
+		map->map_2D_derivative_to_view (map, deriv, x, y): go_nan;
+}
+
 /**
  * gog_chart_map_get_axis_map:
  * @map: a #GogChartMap

Modified: trunk/goffice/graph/gog-chart-map.h
==============================================================================
--- trunk/goffice/graph/gog-chart-map.h	(original)
+++ trunk/goffice/graph/gog-chart-map.h	Mon Nov 24 07:45:24 2008
@@ -42,6 +42,7 @@
 						 GogAxis *axis0, GogAxis *axis1, GogAxis *axis2,
 						 gboolean fill_area);
 void 		 gog_chart_map_2D_to_view	(GogChartMap *map, double x, double y, double *u, double *v);
+double		 gog_chart_map_2D_derivative_to_view (GogChartMap *map, double deriv, double x, double y) ;
 GogAxisMap	*gog_chart_map_get_axis_map 	(GogChartMap *map, unsigned int index);
 gboolean	 gog_chart_map_is_valid 	(GogChartMap *map);
 void		 gog_chart_map_free 		(GogChartMap *map);

Modified: trunk/goffice/graph/gog-series-impl.h
==============================================================================
--- trunk/goffice/graph/gog-series-impl.h	(original)
+++ trunk/goffice/graph/gog-series-impl.h	Mon Nov 24 07:45:24 2008
@@ -105,6 +105,7 @@
 	void (*dim_changed) (GogSeries *series, int dim_i);
 	unsigned (*get_xy_data) (GogSeries const *series,
 					double const **x, double const **y);
+	GogDataset *(*get_interpolation_params) (GogSeries const *series);
 } GogSeriesClass;
 
 #define GOG_SERIES_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST ((k), GOG_SERIES_TYPE, GogSeriesClass))

Modified: trunk/goffice/graph/gog-series-prefs.glade
==============================================================================
--- trunk/goffice/graph/gog-series-prefs.glade	(original)
+++ trunk/goffice/graph/gog-series-prefs.glade	Mon Nov 24 07:45:24 2008
@@ -26,7 +26,7 @@
             <child>
               <widget class="GtkTable" id="interpolation-table">
                 <property name="visible">True</property>
-                <property name="n_rows">2</property>
+                <property name="n_rows">3</property>
                 <property name="n_columns">2</property>
                 <property name="column_spacing">12</property>
                 <property name="row_spacing">6</property>
@@ -34,18 +34,46 @@
                   <placeholder/>
                 </child>
                 <child>
-                  <widget class="GtkCheckButton" id="interpolation-skip-invalid">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="label" translatable="yes">S_kip invalid data</property>
-                    <property name="use_underline">True</property>
-                    <property name="response_id">0</property>
-                    <property name="draw_indicator">True</property>
+                  <widget class="GtkTable" id="clamps-table">
+                    <property name="n_rows">2</property>
+                    <property name="n_columns">2</property>
+                    <property name="column_spacing">12</property>
+                    <property name="row_spacing">6</property>
+                    <child>
+                      <widget class="GtkLabel" id="deriv-last-btn">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">&lt;i&gt;y'&lt;/i&gt;(&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;last&lt;/sub&gt;):</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="deriv-first-btn">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">&lt;i&gt;y'&lt;/i&gt;(&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;first&lt;/sub&gt;):</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="x_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
                   </widget>
                   <packing>
                     <property name="right_attach">2</property>
-                    <property name="top_attach">1</property>
-                    <property name="bottom_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
                   </packing>
                 </child>
                 <child>
@@ -60,6 +88,21 @@
                     <property name="x_options">GTK_FILL</property>
                   </packing>
                 </child>
+                <child>
+                  <widget class="GtkCheckButton" id="interpolation-skip-invalid">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="label" translatable="yes">S_kip invalid data</property>
+                    <property name="use_underline">True</property>
+                    <property name="response_id">0</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
               </widget>
             </child>
           </widget>

Modified: trunk/goffice/graph/gog-series.c
==============================================================================
--- trunk/goffice/graph/gog-series.c	(original)
+++ trunk/goffice/graph/gog-series.c	Mon Nov 24 07:45:24 2008
@@ -424,10 +424,16 @@
 static void
 cb_line_interpolation_changed (GtkComboBox *box, GogSeries *series)
 {
+	GladeXML *gui = g_object_get_data (G_OBJECT (box), "gui");
 	GtkWidget *widget = GTK_WIDGET (g_object_get_data (G_OBJECT(box), "skip-button"));
+	GtkWidget *table = glade_xml_get_widget (gui, "clamps-table");
 	series->interpolation = gtk_combo_box_get_active (box);
 	gtk_widget_set_sensitive (widget, !go_line_interpolation_auto_skip (series->interpolation));
 	widget = GTK_WIDGET (g_object_get_data (G_OBJECT(box), "fill-type"));
+	if (series->interpolation == GO_LINE_INTERPOLATION_CLAMPED_CUBIC_SPLINE)
+		gtk_widget_show (table);
+	else
+		gtk_widget_hide (table);
 	if (widget)
 		gtk_widget_set_sensitive (widget, !go_line_interpolation_auto_skip (series->interpolation));
 	gog_object_emit_changed (GOG_OBJECT (series), FALSE);
@@ -537,6 +543,7 @@
 		if (gui != NULL) {
 			int i;
 			GogAxisSet set = gog_plot_axis_set_pref (gog_series_get_plot (series));
+			GogDataset *clamp_set = gog_series_get_interpolation_params (series);
 			widget = glade_xml_get_widget (gui, "interpolation_prefs");
 			gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
 			widget = glade_xml_get_widget (gui, "interpolation-table");
@@ -564,7 +571,19 @@
 				gtk_widget_set_sensitive (widget, FALSE);
 			g_signal_connect (widget, "toggled",
 					  G_CALLBACK (cb_line_interpolation_skip_changed), series);
-			g_object_set_data_full (G_OBJECT (widget), "gui", gui,
+			if (set) {
+				GtkWidget *w;
+				widget = glade_xml_get_widget (gui, "clamps-table");
+				w = GTK_WIDGET (gog_data_allocator_editor (dalloc, clamp_set, 0, GOG_DATA_SCALAR));
+				gtk_widget_show (w);
+				gtk_table_attach (GTK_TABLE (widget), w, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+				w = GTK_WIDGET (gog_data_allocator_editor (dalloc, clamp_set, 1, GOG_DATA_SCALAR));
+				gtk_widget_show (w);
+				gtk_table_attach (GTK_TABLE (widget), w, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
+				if (series->interpolation != GO_LINE_INTERPOLATION_CLAMPED_CUBIC_SPLINE)
+					gtk_widget_hide (widget);
+			}
+			g_object_set_data_full (G_OBJECT (combo), "gui", gui,
 						(GDestroyNotify) g_object_unref);
 		}
 	}
@@ -1173,3 +1192,15 @@
 	return series_klass->valid_fill_type_list[gtk_combo_box_get_active (combo)];
 }
 #endif
+
+GogDataset *
+gog_series_get_interpolation_params (GogSeries const *series)
+{
+	GogSeriesClass *series_klass;
+
+	g_return_val_if_fail (IS_GOG_SERIES (series), NULL);
+	series_klass = GOG_SERIES_GET_CLASS (series);
+	return (series_klass->get_interpolation_params)?
+			series_klass->get_interpolation_params (series):
+			NULL;
+}
\ No newline at end of file

Modified: trunk/goffice/graph/gog-series.h
==============================================================================
--- trunk/goffice/graph/gog-series.h	(original)
+++ trunk/goffice/graph/gog-series.h	Mon Nov 24 07:45:24 2008
@@ -78,6 +78,8 @@
 GogSeriesFillType gog_series_get_fill_type 	(GogSeries const *series);
 void 		  gog_series_set_fill_type 	(GogSeries *series, GogSeriesFillType fill_type);
 
+GogDataset   *gog_series_get_interpolation_params (GogSeries const *series);
+
 #ifdef GOFFICE_WITH_GTK
 #include <gtk/gtkcombobox.h>
 

Modified: trunk/goffice/utils/go-line.c
==============================================================================
--- trunk/goffice/utils/go-line.c	(original)
+++ trunk/goffice/utils/go-line.c	Mon Nov 24 07:45:24 2008
@@ -97,8 +97,8 @@
 		"parabolic-cspline",	FALSE, FALSE },
 	{ GO_LINE_INTERPOLATION_CUBIC_CUBIC_SPLINE,	N_("Cubic spline with cubic extrapolation"),
 		"cubic-cspline",	FALSE, FALSE },
-/*	{ GO_LINE_INTERPOLATION_CLAMPED_CUBIC_SPLINE,   N_("Clamped cubic spline"),
-		"clamped-cspline",	FALSE, TRUE },*/
+	{ GO_LINE_INTERPOLATION_CLAMPED_CUBIC_SPLINE,   N_("Clamped cubic spline"),
+		"clamped-cspline",	FALSE, TRUE },
 	{ GO_LINE_INTERPOLATION_STEP_START,		N_("Step at start"),
 		"step-start",		TRUE,  FALSE },
 	{ GO_LINE_INTERPOLATION_STEP_END,		N_("Step at end"),

Modified: trunk/goffice/utils/go-line.h
==============================================================================
--- trunk/goffice/utils/go-line.h	(original)
+++ trunk/goffice/utils/go-line.h	Mon Nov 24 07:45:24 2008
@@ -49,7 +49,7 @@
 	GO_LINE_INTERPOLATION_CUBIC_SPLINE,
 	GO_LINE_INTERPOLATION_PARABOLIC_CUBIC_SPLINE,
 	GO_LINE_INTERPOLATION_CUBIC_CUBIC_SPLINE,
-/*	GO_LINE_INTERPOLATION_CLAMPED_CUBIC_SPLINE,*/
+	GO_LINE_INTERPOLATION_CLAMPED_CUBIC_SPLINE,
 	GO_LINE_INTERPOLATION_STEP_START,
 	GO_LINE_INTERPOLATION_STEP_END,
 	GO_LINE_INTERPOLATION_STEP_CENTER_X,

Modified: trunk/plugins/plot_xy/gog-xy.c
==============================================================================
--- trunk/plugins/plot_xy/gog-xy.c	(original)
+++ trunk/plugins/plot_xy/gog-xy.c	Mon Nov 24 07:45:24 2008
@@ -31,6 +31,7 @@
 #include <goffice/graph/gog-chart-map.h>
 #include <goffice/graph/gog-series-lines.h>
 #include <goffice/data/go-data.h>
+#include <goffice/data/go-data-simple.h>
 #include <goffice/utils/go-color.h>
 #include <goffice/utils/go-marker.h>
 #include <goffice/utils/go-format.h>
@@ -1383,17 +1384,107 @@
 
 /****************************************************************************/
 
+typedef struct {
+	GogObject base;
+	GogXYSeries *series;
+	GogDatasetElement *derivs;
+} GogXYInterpolationClamps;
+
+typedef GogObjectClass GogXYInterpolationClampsClass;
+
+#define GOG_XY_INTERPOLATION_CLAMPS_TYPE	(gog_xy_interpolation_clamps_get_type ())
+#define GOG_XY_INTERPOLATION_CLAMPS(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_XY_INTERPOLATION_CLAMPS_TYPE, GogXYInterpolationClamps))
+#define GOG_IS_XY_INTERPOLATION_CLAMPS(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_XY_INTERPOLATION_CLAMPS_TYPE))
+GType gog_xy_interpolation_clamps_get_type (void);
+
+static GObjectClass *interp_parent_klass;
+
+static void
+gog_xy_interpolation_clamps_dataset_dims (GogDataset const *set, int *first, int *last)
+{
+	*first = 0;
+	*last = 1;
+}
+
+static GogDatasetElement *
+gog_xy_interpolation_clamps_dataset_get_elem (GogDataset const *set, int dim_i)
+{
+	GogXYInterpolationClamps *clamps = GOG_XY_INTERPOLATION_CLAMPS (set);
+	g_return_val_if_fail (2 > dim_i, NULL);
+	g_return_val_if_fail (dim_i >= 0, NULL);
+	return clamps->derivs + dim_i;
+}
+
+static void
+gog_xy_interpolation_clamps_dataset_dim_changed (GogDataset *set, int dim_i)
+{
+	GogXYInterpolationClamps *clamps = GOG_XY_INTERPOLATION_CLAMPS (set);
+	clamps->series->clamped_derivs[dim_i] = (IS_GO_DATA_SCALAR ((clamps->derivs + dim_i)->data))?
+		go_data_scalar_get_value (GO_DATA_SCALAR ((clamps->derivs + dim_i)->data)): 0.;
+	gog_object_request_update (GOG_OBJECT (clamps->series));
+}
+
+static void
+gog_xy_interpolation_clamps_dataset_init (GogDatasetClass *iface)
+{
+	iface->get_elem	   = gog_xy_interpolation_clamps_dataset_get_elem;
+	iface->dims	   = gog_xy_interpolation_clamps_dataset_dims;
+	iface->dim_changed = gog_xy_interpolation_clamps_dataset_dim_changed;
+}
+
+static void
+gog_xy_interpolation_clamps_finalize (GObject *obj)
+{
+	GogXYInterpolationClamps *clamps = GOG_XY_INTERPOLATION_CLAMPS (obj);
+	if (clamps->derivs != NULL) {
+		gog_dataset_finalize (GOG_DATASET (obj));
+		g_free (clamps->derivs);
+		clamps->derivs = NULL;
+	}
+	(*interp_parent_klass->finalize) (obj);
+}
+
+static void
+gog_xy_interpolation_clamps_class_init (GObjectClass *klass)
+{
+	interp_parent_klass = g_type_class_peek_parent (klass);
+	klass->finalize	    = gog_xy_interpolation_clamps_finalize;
+}
+
+static void
+gog_xy_interpolation_clamps_init (GogXYInterpolationClamps *clamps)
+{
+	clamps->derivs = g_new0 (GogDatasetElement, 2);
+}
+
+GSF_CLASS_FULL (GogXYInterpolationClamps, gog_xy_interpolation_clamps,
+		NULL, NULL, gog_xy_interpolation_clamps_class_init, NULL,
+		gog_xy_interpolation_clamps_init, GOG_OBJECT_TYPE, 0,
+		GSF_INTERFACE (gog_xy_interpolation_clamps_dataset_init, GOG_DATASET_TYPE))
+
+/****************************************************************************/
+
 typedef GogSeriesClass GogXYSeriesClass;
 
 enum {
 	SERIES_PROP_0,
 	SERIES_PROP_XERRORS,
 	SERIES_PROP_YERRORS,
-	SERIES_PROP_INVALID_AS_ZERO
+	SERIES_PROP_INVALID_AS_ZERO,
+	SERIES_PROP_CLAMP0,
+	SERIES_PROP_CLAMP1
 };
 
 static GogStyledObjectClass *series_parent_klass;
 
+static GogDataset *
+gog_xy_series_get_interpolation_params (GogSeries const *series)
+{
+	GogXYSeries *xy = GOG_XY_SERIES (series);
+	g_return_val_if_fail (xy, NULL);
+	return xy->interpolation_props;
+}
+
 static void
 gog_xy_series_update (GogObject *obj)
 {
@@ -1432,6 +1523,10 @@
 	(GOG_SERIES (series))->acceptable_children = GOG_SERIES_ACCEPT_TREND_LINE;
 	series->x_errors = series->y_errors = NULL;
 	series->hdroplines = series->vdroplines = NULL;
+	series->interpolation_props = g_object_new (GOG_XY_INTERPOLATION_CLAMPS_TYPE, NULL);
+	GOG_XY_INTERPOLATION_CLAMPS (series->interpolation_props)->series = series;
+	gog_dataset_set_dim (series->interpolation_props, 0, go_data_scalar_val_new (0.), NULL);
+	gog_dataset_set_dim (series->interpolation_props, 1, go_data_scalar_val_new (0.), NULL);
 }
 
 static void
@@ -1449,6 +1544,11 @@
 		series->y_errors = NULL;
 	}
 
+	if (series->interpolation_props != NULL) {
+		g_object_unref (series->interpolation_props);
+		series->interpolation_props = NULL;
+	}
+
 	G_OBJECT_CLASS (series_parent_klass)->finalize (obj);
 }
 
@@ -1534,6 +1634,14 @@
 		series->invalid_as_zero = g_value_get_boolean (value);
 		gog_object_request_update (GOG_OBJECT (series));
 		break;
+	case SERIES_PROP_CLAMP0:
+		gog_dataset_set_dim (series->interpolation_props, 0,
+				     go_data_scalar_val_new (g_value_get_double (value)), NULL);
+		break;
+	case SERIES_PROP_CLAMP1:
+		gog_dataset_set_dim (series->interpolation_props, 1,
+				     go_data_scalar_val_new (g_value_get_double (value)), NULL);
+		break;
 	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
 		 break;
 	}
@@ -1555,6 +1663,12 @@
 	case SERIES_PROP_INVALID_AS_ZERO:
 		g_value_set_boolean (value, series->invalid_as_zero);
 		break;
+	case SERIES_PROP_CLAMP0:
+		g_value_set_double (value, series->clamped_derivs[0]);
+		break;
+	case SERIES_PROP_CLAMP1:
+		g_value_set_double (value, series->clamped_derivs[1]);
+		break;
 	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
 		 break;
 	}
@@ -1660,6 +1774,7 @@
 	series_klass->has_interpolation = TRUE;
 	series_klass->has_fill_type	= TRUE;
 	series_klass->series_element_type = GOG_XY_SERIES_ELEMENT_TYPE;
+	series_klass->get_interpolation_params = gog_xy_series_get_interpolation_params;
 
 	gog_object_register_roles (gog_klass, roles, G_N_ELEMENTS (roles));
 
@@ -1681,6 +1796,18 @@
 			_("Replace invalid values by 0 when drawing markers or bubbles"),
 			FALSE, 
 			GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+	g_object_class_install_property (gobject_klass, SERIES_PROP_CLAMP0,
+		g_param_spec_double ("clamp0", 
+			_("Clamp at start"),
+			_("Slope at start of the interpolated curve when using clamped spline interpolation"),
+			-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+	g_object_class_install_property (gobject_klass, SERIES_PROP_CLAMP1,
+		g_param_spec_double ("clamp1", 
+			_("Clamp at end"),
+			_("Slope at end of the interpolated curve when using clamped spline interpolation"),
+			-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
 
 	series_klass->valid_fill_type_list = valid_fill_type_list;
 }

Modified: trunk/plugins/plot_xy/gog-xy.h
==============================================================================
--- trunk/plugins/plot_xy/gog-xy.h	(original)
+++ trunk/plugins/plot_xy/gog-xy.h	Mon Nov 24 07:45:24 2008
@@ -95,6 +95,7 @@
     GogObject	  *vdroplines;
 	gboolean 	   invalid_as_zero;
 	double		   clamped_derivs[2]; /* start and and slopes for clamped cubic splines */
+	GogDataset	  *interpolation_props;
 } GogXYSeries;
 
 #define GOG_XY_SERIES_TYPE	(gog_xy_series_get_type ())



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]