goffice r2272 - in trunk: . goffice/graph goffice/utils plugins/plot_radar plugins/plot_xy



Author: jbrefort
Date: Tue Nov 11 09:58:27 2008
New Revision: 2272
URL: http://svn.gnome.org/viewvc/goffice?rev=2272&view=rev

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

	* goffice/graph/gog-chart-map.c: (make_path_linear),
	(make_path_spline), (make_path_cspline), (xy_make_path_step),
	(xy_make_path), (polar_make_path_step), (polar_make_path),
	(gog_chart_map_make_path): add new spline interpolation modes.
	* goffice/graph/gog-chart-map.h: ditto.
	* goffice/graph/gog-reg-curve.c: (gog_reg_curve_view_render): use
	natural cubic splines instead of Bezier splines.
	* goffice/graph/gog-series-impl.h: allow interpolation over invalid
	data.
	* goffice/graph/gog-series-prefs.glade: add new spline interpolation
	modes and allow interpolation over invalid data.
	* goffice/graph/gog-series.c: (gog_series_set_property),
	(gog_series_get_property), (cb_line_interpolation_changed),
	(cb_line_interpolation_skip_changed), (gog_series_populate_editor),
	(gog_series_class_init): ditto.
	* goffice/graph/gog-smoothed-curve.c: 
	(gog_smoothed_curve_view_render): update after gog_chart_map_make_path
	signature change.
	* goffice/utils/Makefile.am: add bezier splines evaluation.
	* goffice/utils/go-line.c: (go_line_interpolation_as_label),
	(go_line_interpolation_supports_radial),
	(go_line_interpolation_auto_skip): add new spline interpolation modes.
	* goffice/utils/go-line.h: ditto.
	* plugins/plot_radar/gog-radar.c: (gog_rt_view_render): update after
	gog_chart_map_make_path signature change.
	* plugins/plot_xy/gog-xy.c: (gog_xy_view_render): add new spline
	interpolation modes.
	* plugins/plot_xy/gog-xy.h: ditto.



Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/goffice/graph/gog-chart-map.c
   trunk/goffice/graph/gog-chart-map.h
   trunk/goffice/graph/gog-reg-curve.c
   trunk/goffice/graph/gog-series-impl.h
   trunk/goffice/graph/gog-series-prefs.glade
   trunk/goffice/graph/gog-series.c
   trunk/goffice/graph/gog-smoothed-curve.c
   trunk/goffice/utils/Makefile.am
   trunk/goffice/utils/go-line.c
   trunk/goffice/utils/go-line.h
   trunk/plugins/plot_radar/gog-radar.c
   trunk/plugins/plot_xy/gog-xy.c
   trunk/plugins/plot_xy/gog-xy.h

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Tue Nov 11 09:58:27 2008
@@ -10,6 +10,7 @@
 	* Add XYZ series based contour plots.
 	* Drop the libgome dependency. [#558709]
 	* Made spline interpolation really use Bezier cubic splines.
+	* Add closed Bezier and cubic spline interpolation.
 
 Morten:
 	* Plug leaks.

Modified: trunk/goffice/graph/gog-chart-map.c
==============================================================================
--- trunk/goffice/graph/gog-chart-map.c	(original)
+++ trunk/goffice/graph/gog-chart-map.c	Tue Nov 11 09:58:27 2008
@@ -22,6 +22,8 @@
 #include <goffice/graph/gog-chart-map.h>
 #include <goffice/math/go-cspline.h>
 #include <goffice/math/go-math.h>
+#include <goffice/math/go-rangefunc.h>
+#include <goffice/utils/go-bezier.h>
 #include <goffice/utils/go-line.h>
 #include <goffice/utils/go-path.h>
 #include <goffice/utils/go-geometry.h>
@@ -35,7 +37,7 @@
 
 	void 	 (*map_2D_to_view) 	(GogChartMap *map, double x, double y, double *u, double *v);
 	GOPath  *(*make_path)	   	(GogChartMap *map, double const *x, double const *y, int n_points,
-					 GOLineInterpolation interpolation);
+					 GOLineInterpolation interpolation, gboolean skip_invalid, gpointer data);
 	GOPath  *(*make_close_path)	(GogChartMap *map, double const *x, double const *y, int n_points,
 					 GogSeriesFillType fill_type);
 };
@@ -185,7 +187,7 @@
 static GOPath *
 make_path_linear (GogChartMap *map,
 		  double const *x, double const *y,
-		  int n_points, gboolean is_polar)
+		  int n_points, gboolean is_polar, gboolean skip_invalid)
 {
 	GOPath *path;
 	int i, n_valid_points = 0;
@@ -222,7 +224,7 @@
 				go_path_move_to (path, xx, yy);
 			else
 				go_path_line_to (path, xx, yy);
-		} else
+		} else if (!skip_invalid)
 			n_valid_points = 0;
 	}
 
@@ -232,7 +234,7 @@
 static GOPath *
 make_path_spline (GogChartMap *map,
 		  double const *x, double const *y, int n_points,
-		  gboolean is_polar)
+		  gboolean is_polar, gboolean closed, gboolean skip_invalid)
 {
 	GOPath *path;
 	int i, n_valid_points = 0;
@@ -240,7 +242,8 @@
 	double u, v;
 	double yy, yy_min, yy_max;
 	gboolean is_inverted;
-	struct GOCSpline *splinex, *spliney;
+	//struct GOCSpline *splinex, *spliney;
+	struct GOBezierSpline *spline;
 
 	path = go_path_new ();
 	if (n_points < 1)
@@ -273,80 +276,135 @@
 			tt[n_valid_points] = n_valid_points;
 			n_valid_points++;
 		} else {
+			if (closed || skip_invalid)
+				continue;
+			if (n_valid_points == 2) {
+				go_path_move_to (path, uu[0], vv[0]);
+				go_path_line_to (path, uu[1], vv[1]);
+			} else if (n_valid_points > 2) {
+				/* evaluate the spline */
+				spline = go_bezier_spline_init (uu, vv, n_valid_points, closed);
+				path = go_bezier_spline_to_path (spline);
+				go_bezier_spline_destroy (spline);
+			}
+			n_valid_points = 0;
+		}
+	}
+	if (n_valid_points == 2) {
+		go_path_move_to (path, uu[0], vv[0]);
+		go_path_line_to (path, uu[1], vv[1]);
+	} else if (n_valid_points > 2) {
+		/* evaluate the spline */
+		spline = go_bezier_spline_init (uu, vv, n_valid_points, closed);
+		path = go_bezier_spline_to_path (spline);
+		go_bezier_spline_destroy (spline);
+	}
+
+	g_free (uu);
+	g_free (vv);
+	g_free (tt);
+	return path;
+}
+
+static GOPath *
+make_path_cspline (GogChartMap *map,
+		  double const *x, double const *y, int n_points,
+		  gboolean is_polar, GOCSplineType type, gboolean skip_invalid,
+		  gpointer data)
+{
+	GOPath *path;
+	int i, n_valid_points = 0;
+	double *uu, *vv, u, v;
+	double p0, p1; /* clamped derivatives */
+	struct GOCSpline *spline;
+
+	path = go_path_new ();
+	if (n_points < 1 || !go_range_increasing (x, n_points))
+		return path;
+
+	uu = g_new (double, n_points);
+	vv = g_new (double, n_points);
+	n_valid_points = 0;
+
+	if (type == GO_CSPLINE_CLAMPED && data != NULL) {
+		p0 = ((double*) data)[0];
+		p1 = ((double*) data)[1];
+	} else
+		p0 = p1 = 0.;
+
+	for (i = 0; i < n_points; i++) {
+		gog_chart_map_2D_to_view (map,
+					  x != NULL ? x[i] : i + 1, y != NULL ? y[i] : i + 1,
+					  &u, &v);
+		if (go_finite (u)
+		    && go_finite (v)
+		    && fabs (u) != DBL_MAX
+		    && fabs (v) != DBL_MAX) {
+			uu[n_valid_points] = u;
+			vv[n_valid_points] = v;
+			n_valid_points++;
+		} else {
+			if (skip_invalid || type == GO_CSPLINE_CLAMPED)
+				continue;
 			if (n_valid_points == 2)
 				go_path_line_to (path, uu[1], vv[1]);
 			else if (n_valid_points > 2) {
 				/* evaluate the spline */
-				splinex = go_cspline_init (tt, uu, n_valid_points, GO_CSPLINE_NATURAL, 0., 0.);
-				spliney = go_cspline_init (tt, vv, n_valid_points, GO_CSPLINE_NATURAL, 0., 0.);
-				if (splinex && spliney) {
+				spline = go_cspline_init (uu, vv, n_valid_points, type, p0, p1);
+				if (spline) {
 					double x0, x1, x2, x3, y0, y1, y2, y3;
-					path = go_path_new ();
 					x0 = uu[0];
 					y0 = vv[0];
 					go_path_move_to (path, x0, y0);
-					for (i = 1; i < splinex->n; i++) {
+					for (i = 1; i < spline->n; i++) {
 						x3 = uu[i];
 						y3 = vv[i];
-						x1 = x0 + splinex->c[i-1] / 3.;
-						x2 = x0 + 2. * splinex->c[i-1] / 3. + splinex->b[i-1] / 3.;
-						y1 = y0 + spliney->c[i-1] / 3.;
-						y2 = y0 + 2. * spliney->c[i-1] / 3. + spliney->b[i-1] / 3.;
+						u = x3 - x0;
+						x1 = (2. * x0 + x3) / 3.;
+						x2 = (x0 + 2. * x3) / 3.;
+						y1 = y0 + spline->c[i-1] / 3. * u;
+						y2 = y0 + (2. * spline->c[i-1] + spline->b[i-1] * u) / 3. * u;
 						go_path_curve_to (path, x1, y1, x2, y2, x3, y3);
 						x0 = x3;
 						y0 = y3;
 					}
-					go_cspline_destroy (splinex);
-					go_cspline_destroy (spliney);
-				} else if (splinex)
-					go_cspline_destroy (splinex);
-				else if (spliney)
-					go_cspline_destroy (spliney);
+					go_cspline_destroy (spline);
+				}
 			}
-			n_valid_points = 0;
 		}
 	}
-	if (n_valid_points == 2)
+	if (n_valid_points == 2) {
+		go_path_move_to (path, uu[0], vv[0]);
 		go_path_line_to (path, uu[1], vv[1]);
-	else if (n_valid_points > 2) {
-		/* evaluate the spline */
-		splinex = go_cspline_init (tt, uu, n_valid_points, GO_CSPLINE_NATURAL, 0., 0.);
-		spliney = go_cspline_init (tt, vv, n_valid_points, GO_CSPLINE_NATURAL, 0., 0.);
-		if (splinex && spliney) {
+	} else if (n_valid_points > 2) {
+		spline = go_cspline_init (uu, vv, n_valid_points, type, p0, p1);
+		if (spline) {
 			double x0, x1, x2, x3, y0, y1, y2, y3;
-			path = go_path_new ();
 			x0 = uu[0];
 			y0 = vv[0];
 			go_path_move_to (path, x0, y0);
-			for (i = 1; i < splinex->n; i++) {
+			for (i = 1; i < spline->n; i++) {
 				x3 = uu[i];
 				y3 = vv[i];
-				x1 = x0 + splinex->c[i-1] / 3.;
-				x2 = x0 + 2. * splinex->c[i-1] / 3. + splinex->b[i-1] / 3.;
-				y1 = y0 + spliney->c[i-1] / 3.;
-				y2 = y0 + 2. * spliney->c[i-1] / 3. + spliney->b[i-1] / 3.;
+				u = x3 - x0;
+				x1 = (2. * x0 + x3) / 3.;
+				x2 = (x0 + 2. * x3) / 3.;
+				y1 = y0 + spline->c[i-1] / 3. * u;
+				y2 = y0 + (2. * spline->c[i-1] + spline->b[i-1] * u) / 3. * u;
 				go_path_curve_to (path, x1, y1, x2, y2, x3, y3);
 				x0 = x3;
 				y0 = y3;
 			}
-			go_cspline_destroy (splinex);
-			go_cspline_destroy (spliney);
-		} else if (splinex)
-			go_cspline_destroy (splinex);
-		else if (spliney)
-			go_cspline_destroy (spliney);
-			
+			go_cspline_destroy (spline);
+		}
 	}
 
-	g_free (uu);
-	g_free (vv);
-	g_free (tt);
 	return path;
 }
 
 static GOPath *
 xy_make_path_step (GogChartMap *map, double const *x, double const *y, int n_points,
-		   GOLineInterpolation interpolation)
+		   GOLineInterpolation interpolation, gboolean skip_invalid)
 {
 	GOPath *path;
 	int i, n_valid_points = 0;
@@ -392,7 +450,7 @@
 			go_path_line_to (path, xx, yy);
 			last_xx = xx;
 			last_yy = yy;
-		} else 
+		} else if (!skip_invalid)
 			n_valid_points = 0;
 	}
 
@@ -403,22 +461,37 @@
 
 static GOPath *
 xy_make_path (GogChartMap *map, double const *x, double const *y, 
-	      int n_points, GOLineInterpolation interpolation)
+	      int n_points, GOLineInterpolation interpolation, gboolean skip_invalid, gpointer data)
 {
 	GOPath *path = NULL;
 
 	switch (interpolation) {
 		case GO_LINE_INTERPOLATION_LINEAR:
-			path = make_path_linear (map, x, y, n_points, FALSE);
+			path = make_path_linear (map, x, y, n_points, FALSE, skip_invalid);
 			break;
 		case GO_LINE_INTERPOLATION_SPLINE:
-			path = make_path_spline (map, x, y, n_points, FALSE);
+			path = make_path_spline (map, x, y, n_points, FALSE, FALSE, skip_invalid);
+			break;
+		case GO_LINE_INTERPOLATION_CLOSED_SPLINE:
+			path = make_path_spline (map, x, y, n_points, TRUE, TRUE, skip_invalid);
+			break;
+		case GO_LINE_INTERPOLATION_CUBIC_SPLINE:
+			path = make_path_cspline (map, x, y, n_points, TRUE, GO_CSPLINE_NATURAL, skip_invalid, data);
 			break;
+		case GO_LINE_INTERPOLATION_PARABOLIC_CUBIC_SPLINE:
+			path = make_path_cspline (map, x, y, n_points, TRUE, GO_CSPLINE_PARABOLIC, skip_invalid, data);
+			break;
+		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:
+			path = make_path_cspline (map, x, y, n_points, TRUE, GO_CSPLINE_CLAMPED, skip_invalid, data);
+			break;*/
 		case GO_LINE_INTERPOLATION_STEP_START:
 		case GO_LINE_INTERPOLATION_STEP_END:
 		case GO_LINE_INTERPOLATION_STEP_CENTER_X:
 		case GO_LINE_INTERPOLATION_STEP_CENTER_Y:
-			path = xy_make_path_step (map, x, y, n_points, interpolation);
+			path = xy_make_path_step (map, x, y, n_points, interpolation, skip_invalid);
 			break;
 		default:
 			g_assert_not_reached ();
@@ -506,7 +579,7 @@
 
 static GOPath *
 polar_make_path_step (GogChartMap *map, double const *x, double const *y, int n_points,
-		      GOLineInterpolation interpolation)
+		      GOLineInterpolation interpolation, gboolean skip_invalid)
 {
 	GogChartMapPolarData *polar_parms;
 	GOPath *path;
@@ -583,7 +656,7 @@
 			last_yy = yy;
 			last_theta = theta;
 			last_rho = rho;
-		} else
+		} else if (!skip_invalid)
 			n_valid_points = 0;
 	}
 
@@ -592,22 +665,25 @@
 
 static GOPath *
 polar_make_path (GogChartMap *map, double const *x, double const *y,
-		 int n_points, GOLineInterpolation interpolation)
+		 int n_points, GOLineInterpolation interpolation, gboolean skip_invalid, gpointer data)
 {
 	GOPath *path = NULL;
 
 	switch (interpolation) {
 		case GO_LINE_INTERPOLATION_LINEAR:
-			path = make_path_linear (map, x, y, n_points, TRUE);
+			path = make_path_linear (map, x, y, n_points, TRUE, skip_invalid);
 			break;
 		case GO_LINE_INTERPOLATION_SPLINE:
-			path = make_path_spline (map, x, y, n_points, TRUE);
+			path = make_path_spline (map, x, y, n_points, TRUE, FALSE, skip_invalid);
+			break;
+		case GO_LINE_INTERPOLATION_CLOSED_SPLINE:
+			path = make_path_spline (map, x, y, n_points, TRUE, TRUE, skip_invalid);
 			break;
 		case GO_LINE_INTERPOLATION_STEP_START:
 		case GO_LINE_INTERPOLATION_STEP_END:
 		case GO_LINE_INTERPOLATION_STEP_CENTER_X:
 		case GO_LINE_INTERPOLATION_STEP_CENTER_Y:
-			path = polar_make_path_step (map, x, y, n_points, interpolation);
+			path = polar_make_path_step (map, x, y, n_points, interpolation, skip_invalid);
 			break;
 		default:
 			g_assert_not_reached ();
@@ -883,16 +959,17 @@
  * @y: y data
  * @n_points: number of points
  * @interpolation: interpolation type
+ * @skip_invalid: whether to ignore invalid data or interrupt the interpolation
  *
  * Returns: a new GOPath using @x and @y data, each valid point being connected with respect to @interpolation.
  **/
 GOPath *
 gog_chart_map_make_path (GogChartMap *map, double const *x, double const *y,
 			 int n_points,
-			 GOLineInterpolation interpolation)
+			 GOLineInterpolation interpolation, gboolean skip_invalid, gpointer data)
 {
 	if (map->make_path != NULL)
-		return (map->make_path) (map, x, y, n_points, interpolation);
+		return (map->make_path) (map, x, y, n_points, interpolation, skip_invalid, data);
 
 	return NULL;
 }

Modified: trunk/goffice/graph/gog-chart-map.h
==============================================================================
--- trunk/goffice/graph/gog-chart-map.h	(original)
+++ trunk/goffice/graph/gog-chart-map.h	Tue Nov 11 09:58:27 2008
@@ -47,8 +47,8 @@
 void		 gog_chart_map_free 		(GogChartMap *map);
 
 GOPath 		*gog_chart_map_make_path 	(GogChartMap *map, double const *x, double const *y, 
-						 int n_points, 
-						 GOLineInterpolation interpolation);
+						 int n_points, GOLineInterpolation interpolation,
+						 gboolean skip_invalid, gpointer data);
 GOPath 		*gog_chart_map_make_close_path 	(GogChartMap *map, double const *x, double const *y, 
 						 int n_points, 
 						 GogSeriesFillType fill_type);

Modified: trunk/goffice/graph/gog-reg-curve.c
==============================================================================
--- trunk/goffice/graph/gog-reg-curve.c	(original)
+++ trunk/goffice/graph/gog-reg-curve.c	Tue Nov 11 09:58:27 2008
@@ -329,7 +329,7 @@
 		y[i] = gog_reg_curve_get_value_at (rc, x[i]);
 	}
 
-	path = gog_chart_map_make_path (chart_map, x, y, rc->ninterp + 1, GO_LINE_INTERPOLATION_SPLINE);
+	path = gog_chart_map_make_path (chart_map, x, y, rc->ninterp + 1, GO_LINE_INTERPOLATION_CUBIC_SPLINE, FALSE, NULL);
 	style = GOG_STYLED_OBJECT (rc)->style;
 	gog_renderer_push_style (view->renderer, style);
 	gog_renderer_stroke_serie (view->renderer, path);

Modified: trunk/goffice/graph/gog-series-impl.h
==============================================================================
--- trunk/goffice/graph/gog-series-impl.h	(original)
+++ trunk/goffice/graph/gog-series-impl.h	Tue Nov 11 09:58:27 2008
@@ -88,6 +88,7 @@
 	GList		  *overrides;  /* GogSeriesElement (individual points) */
 
 	GOLineInterpolation	interpolation;
+	gboolean interpolation_skip_invalid;
 };
 
 typedef struct {

Modified: trunk/goffice/graph/gog-series-prefs.glade
==============================================================================
--- trunk/goffice/graph/gog-series-prefs.glade	(original)
+++ trunk/goffice/graph/gog-series-prefs.glade	Tue Nov 11 09:58:27 2008
@@ -1,202 +1,114 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
 <glade-interface>
-
-<widget class="GtkWindow" id="interpolation_prefs_window">
-  <property name="title" translatable="yes"></property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-
-  <child>
-    <widget class="GtkVBox" id="interpolation_prefs">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child>
-	<widget class="GtkLabel" id="interpolation-label">
-	  <property name="visible">True</property>
-	  <property name="label" translatable="yes">&lt;b&gt;Interpolation&lt;/b&gt;</property>
-	  <property name="use_underline">False</property>
-	  <property name="use_markup">True</property>
-	  <property name="justify">GTK_JUSTIFY_LEFT</property>
-	  <property name="wrap">False</property>
-	  <property name="selectable">False</property>
-	  <property name="xalign">0</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	  <property name="width_chars">-1</property>
-	  <property name="single_line_mode">False</property>
-	  <property name="angle">0</property>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkAlignment" id="alignment8">
-	  <property name="visible">True</property>
-	  <property name="xalign">0.5</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xscale">1</property>
-	  <property name="yscale">1</property>
-	  <property name="top_padding">6</property>
-	  <property name="bottom_padding">0</property>
-	  <property name="left_padding">18</property>
-	  <property name="right_padding">0</property>
-
-	  <child>
-	    <widget class="GtkHBox" id="interpolation-hbox">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">12</property>
-
-	      <child>
-		<widget class="GtkLabel" id="interpolation-type-label">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">_Type:</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.460000008345</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkComboBox" id="interpolation_combo">
-		  <property name="visible">True</property>
-		  <property name="items" translatable="yes">Linear
-Spline
-Step at start
-Step at end
-Step at center
-Step to average</property>
-		  <property name="add_tearoffs">False</property>
-		  <property name="focus_on_click">True</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-<widget class="GtkWindow" id="fill_type_prefs_window">
-  <property name="title" translatable="yes"></property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-
-  <child>
-    <widget class="GtkVBox" id="fill_type_prefs">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child>
-	<widget class="GtkHBox" id="hbox1">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">12</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="label2">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Fill _to:</property>
-	      <property name="use_underline">True</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0</property>
-	      <property name="yalign">0.460000008345</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkComboBox" id="fill_type_combo">
-	      <property name="visible">True</property>
-	      <property name="items" translatable="yes">content</property>
-	      <property name="add_tearoffs">False</property>
-	      <property name="focus_on_click">True</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
+  <widget class="GtkWindow" id="interpolation_prefs_window">
+    <child>
+      <widget class="GtkVBox" id="interpolation_prefs">
+        <property name="visible">True</property>
+        <child>
+          <widget class="GtkLabel" id="interpolation-label">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">&lt;b&gt;Interpolation&lt;/b&gt;</property>
+            <property name="use_markup">True</property>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkAlignment" id="alignment8">
+            <property name="visible">True</property>
+            <property name="top_padding">6</property>
+            <property name="left_padding">18</property>
+            <child>
+              <widget class="GtkTable" id="interpolation-table">
+                <property name="visible">True</property>
+                <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>
+                  <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>
+                  <packing>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="interpolation-type-label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="yalign">0.46000000834465027</property>
+                    <property name="label" translatable="yes">_Type:</property>
+                    <property name="use_underline">True</property>
+                  </widget>
+                  <packing>
+                    <property name="x_options">GTK_FILL</property>
+                  </packing>
+                </child>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+  <widget class="GtkWindow" id="fill_type_prefs_window">
+    <child>
+      <widget class="GtkVBox" id="fill_type_prefs">
+        <property name="visible">True</property>
+        <child>
+          <widget class="GtkHBox" id="hbox1">
+            <property name="visible">True</property>
+            <property name="spacing">12</property>
+            <child>
+              <widget class="GtkLabel" id="label2">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0.46000000834465027</property>
+                <property name="label" translatable="yes">Fill _to:</property>
+                <property name="use_underline">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkComboBox" id="fill_type_combo">
+                <property name="visible">True</property>
+                <property name="items" translatable="yes">content</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
 </glade-interface>

Modified: trunk/goffice/graph/gog-series.c
==============================================================================
--- trunk/goffice/graph/gog-series.c	(original)
+++ trunk/goffice/graph/gog-series.c	Tue Nov 11 09:58:27 2008
@@ -265,6 +265,7 @@
 	SERIES_PROP_0,
 	SERIES_PROP_HAS_LEGEND,
 	SERIES_PROP_INTERPOLATION,
+	SERIES_PROP_INTERPOLATION_SKIP_INVALID,
 	SERIES_PROP_FILL_TYPE
 };
 
@@ -348,6 +349,9 @@
 	case SERIES_PROP_INTERPOLATION:
 		series->interpolation = go_line_interpolation_from_str (g_value_get_string (value));
 		break;
+	case SERIES_PROP_INTERPOLATION_SKIP_INVALID:
+		series->interpolation_skip_invalid = g_value_get_boolean (value);
+		break;
 	case SERIES_PROP_FILL_TYPE:
 		name = g_value_get_string (value);
 		for (i = 0; i < G_N_ELEMENTS (_fill_type_infos); i++)
@@ -375,6 +379,9 @@
 	case SERIES_PROP_INTERPOLATION:
 		g_value_set_string (value, go_line_interpolation_as_str (series->interpolation));
 		break;
+	case SERIES_PROP_INTERPOLATION_SKIP_INVALID:
+		g_value_set_boolean (value, series->interpolation_skip_invalid);
+		break;
 	case SERIES_PROP_FILL_TYPE:
 		g_value_set_string (value, _fill_type_infos[series->fill_type].name);
 		break;
@@ -417,7 +424,19 @@
 static void
 cb_line_interpolation_changed (GtkComboBox *box, GogSeries *series)
 {
+	GtkWidget *widget = GTK_WIDGET (g_object_get_data (G_OBJECT(box), "skip-button"));
 	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 (widget)
+		gtk_widget_set_sensitive (widget, !go_line_interpolation_auto_skip (series->interpolation));
+	gog_object_emit_changed (GOG_OBJECT (series), FALSE);
+}
+
+static void
+cb_line_interpolation_skip_changed (GtkToggleButton *btn, GogSeries *series)
+{
+	series->interpolation_skip_invalid = gtk_toggle_button_get_active (btn);
 	gog_object_emit_changed (GOG_OBJECT (series), FALSE);
 }
 
@@ -444,6 +463,7 @@
 	GogDataset *set = GOG_DATASET (gobj);
 	GogSeriesDesc const *desc;
 	GogDataType data_type;
+	GtkComboBox *combo = NULL;
 
 	g_return_if_fail (series->plot != NULL);
 
@@ -515,12 +535,35 @@
 
 		gui = go_libglade_new ("gog-series-prefs.glade", "interpolation_prefs", GETTEXT_PACKAGE, cc);
 		if (gui != NULL) {
+			int i;
+			GogAxisSet set = gog_plot_axis_set_pref (gog_series_get_plot (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_combo");
-			gtk_combo_box_set_active (GTK_COMBO_BOX (widget), series->interpolation);
-			g_signal_connect (widget, "changed",
+			widget = glade_xml_get_widget (gui, "interpolation-table");
+			/* create an interpolation type combo and populate it */
+			combo = GTK_COMBO_BOX (gtk_combo_box_new_text ());
+			if (set & GOG_AXIS_RADIAL)
+				for (i = 0; i < GO_LINE_INTERPOLATION_MAX; i++) {
+					if (go_line_interpolation_supports_radial (i))
+						gtk_combo_box_append_text (combo, _(go_line_interpolation_as_label (i)));
+				}
+			else
+				for (i = 0; i < GO_LINE_INTERPOLATION_MAX; i++)
+					gtk_combo_box_append_text (combo, _(go_line_interpolation_as_label (i)));
+			gtk_combo_box_set_active (combo, series->interpolation);
+			g_signal_connect (combo, "changed",
 					  G_CALLBACK (cb_line_interpolation_changed), series);
+			gtk_table_attach (GTK_TABLE (widget), GTK_WIDGET (combo), 1, 2,
+					  0, 1, (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
+					  (GtkAttachOptions) (GTK_FILL | GTK_EXPAND), 0, 0);
+			gtk_widget_show_all (widget);
+			widget = glade_xml_get_widget (gui, "interpolation-skip-invalid");
+			g_object_set_data (G_OBJECT (combo), "skip-button", widget); 
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), series->interpolation_skip_invalid);
+			if (go_line_interpolation_auto_skip (series->interpolation))
+				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,
 						(GDestroyNotify) g_object_unref);
 		}
@@ -537,6 +580,10 @@
 			gog_series_populate_fill_type_combo (GOG_SERIES (series), GTK_COMBO_BOX (widget));
 			g_signal_connect (G_OBJECT (widget), "changed",
 					  G_CALLBACK (cb_fill_type_changed), series);
+			if (combo)
+				g_object_set_data (G_OBJECT (combo), "fill-type", widget);
+			if (series->interpolation == GO_LINE_INTERPOLATION_CLOSED_SPLINE)
+				gtk_widget_set_sensitive (widget, FALSE);
 			widget = glade_xml_get_widget (gui, "fill_type_prefs");
 			gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0);
 			g_object_set_data_full (G_OBJECT (widget), "gui", gui,
@@ -625,6 +672,12 @@
 			_("Type of line interpolation"),
 			"linear",
 			GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+	g_object_class_install_property (gobject_klass, SERIES_PROP_INTERPOLATION_SKIP_INVALID,
+		g_param_spec_boolean ("interpolation-skip-invalid", 
+			_("Interpolation skip invalid"),
+			_("Should the series interpolation ignore the invalid data"),
+			FALSE,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
 	g_object_class_install_property (gobject_klass, SERIES_PROP_FILL_TYPE,
 		g_param_spec_string ("fill-type", 
 			_("Fill type"),

Modified: trunk/goffice/graph/gog-smoothed-curve.c
==============================================================================
--- trunk/goffice/graph/gog-smoothed-curve.c	(original)
+++ trunk/goffice/graph/gog-smoothed-curve.c	Tue Nov 11 09:58:27 2008
@@ -122,7 +122,7 @@
 	gog_renderer_push_clip_rectangle (view->renderer, view->residual.x, view->residual.y,
 					  view->residual.w, view->residual.h);
 
-	path = gog_chart_map_make_path (chart_map, curve->x, curve->y, curve->nb, GO_LINE_INTERPOLATION_LINEAR);
+	path = gog_chart_map_make_path (chart_map, curve->x, curve->y, curve->nb, GO_LINE_INTERPOLATION_LINEAR, FALSE, NULL);
 	style = GOG_STYLED_OBJECT (curve)->style;
 	gog_renderer_push_style (view->renderer, style);
 	gog_renderer_stroke_serie (view->renderer, path);

Modified: trunk/goffice/utils/Makefile.am
==============================================================================
--- trunk/goffice/utils/Makefile.am	(original)
+++ trunk/goffice/utils/Makefile.am	Tue Nov 11 09:58:27 2008
@@ -27,7 +27,8 @@
 	go-glib-extras.c	\
 	go-libxml-extras.c	\
 	go-pango-extras.c	\
-	go-persist.c
+	go-persist.c	\
+	go-bezier.c
 
 libgoffice_utils_ladir = $(goffice_include_dir)/utils
 libgoffice_utils_la_HEADERS = 	\
@@ -52,7 +53,8 @@
 	go-glib-extras.h	\
 	go-libxml-extras.h	\
 	go-pango-extras.h	\
-	go-persist.h
+	go-persist.h	\
+	go-bezier.h
 
 CLEANFILES =			\
 	go-marshalers.h		\

Modified: trunk/goffice/utils/go-line.c
==============================================================================
--- trunk/goffice/utils/go-line.c	(original)
+++ trunk/goffice/utils/go-line.c	Tue Nov 11 09:58:27 2008
@@ -81,14 +81,32 @@
 	GOLineInterpolation type;
 	char const *label;
 	char const *name;
+	gboolean supports_radial;
+	gboolean auto_skip;
 } line_interpolations[GO_LINE_INTERPOLATION_MAX] =
 {
-	{ GO_LINE_INTERPOLATION_LINEAR,		N_("Linear"), 		"linear" },
-	{ GO_LINE_INTERPOLATION_SPLINE,		N_("Spline"),		"spline" },
-	{ GO_LINE_INTERPOLATION_STEP_START,	N_("Step at start"), 	"step-start" },
-	{ GO_LINE_INTERPOLATION_STEP_END,	N_("Step at end"),	"step-end" },
-	{ GO_LINE_INTERPOLATION_STEP_CENTER_X,	N_("Step at center"),	"step-center-x" },
-	{ GO_LINE_INTERPOLATION_STEP_CENTER_Y,	N_("Step to mean"),	"step-center-y" }
+	{ GO_LINE_INTERPOLATION_LINEAR,			N_("Linear"),
+		"linear",		TRUE,  FALSE },
+	{ GO_LINE_INTERPOLATION_SPLINE,			N_("Bezier cubic spline"),
+		"spline",		TRUE,  FALSE },
+	{ GO_LINE_INTERPOLATION_CLOSED_SPLINE,		N_("Closed Bezier cubic spline"),
+		"closed-spline",	TRUE,  TRUE },
+	{ GO_LINE_INTERPOLATION_CUBIC_SPLINE,		N_("Natural cubic spline"),
+		"cspline",		FALSE, FALSE },
+	{ GO_LINE_INTERPOLATION_PARABOLIC_CUBIC_SPLINE,	N_("Cubic spline with parabolic extrapolation"),
+		"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_STEP_START,		N_("Step at start"),
+		"step-start",		TRUE,  FALSE },
+	{ GO_LINE_INTERPOLATION_STEP_END,		N_("Step at end"),
+		"step-end",		TRUE,  FALSE },
+	{ GO_LINE_INTERPOLATION_STEP_CENTER_X,		N_("Step at center"),
+		"step-center-x",	TRUE,  FALSE },
+	{ GO_LINE_INTERPOLATION_STEP_CENTER_Y,		N_("Step to mean"),
+		"step-center-y",	TRUE,  FALSE }
 };
 
 /**
@@ -265,3 +283,66 @@
 	}
 	return ret;
 }
+
+/**
+ * go_line_interpolation_as_label:
+ * @type: an interpolation type
+ *
+ * Returns: a pointer to the label of @type, or the name of
+ * %GO_LINE_INTERPOLATION_LINEAR if type is invalid.
+ * The returned string should not be freed.
+ **/
+char const *
+go_line_interpolation_as_label (GOLineInterpolation type)
+{
+	unsigned i;
+	char const *ret = _("Linear");
+
+	for (i = 0; i < G_N_ELEMENTS (line_interpolations); i++) {
+		if (line_interpolations[i].type == type) {
+			ret = _(line_interpolations[i].label);
+			break;
+		}
+	}
+	return ret;
+}
+
+/**
+ * go_line_interpolation_as_str:
+ * @type: an interpolation type
+ *
+ * Returns: TRUE if the line interpolation type can be used with radial
+ * axes set, FALSE it it can't.
+ **/
+gboolean
+go_line_interpolation_supports_radial (GOLineInterpolation type)
+{
+	unsigned i;
+
+	for (i = 0; i < G_N_ELEMENTS (line_interpolations); i++) {
+		if (line_interpolations[i].type == type) {
+			return line_interpolations[i].supports_radial;
+		}
+	}
+	return FALSE;
+}
+
+/**
+ * go_line_interpolation_as_str:
+ * @type: an interpolation type
+ *
+ * Returns: TRUE if the line interpolation type forces skipping invalid
+ * data, FALSE if it is only optional.
+ **/
+gboolean
+go_line_interpolation_auto_skip	(GOLineInterpolation type)
+{
+	unsigned i;
+
+	for (i = 0; i < G_N_ELEMENTS (line_interpolations); i++) {
+		if (line_interpolations[i].type == type) {
+			return line_interpolations[i].auto_skip;
+		}
+	}
+	return FALSE;
+}

Modified: trunk/goffice/utils/go-line.h
==============================================================================
--- trunk/goffice/utils/go-line.h	(original)
+++ trunk/goffice/utils/go-line.h	Tue Nov 11 09:58:27 2008
@@ -45,6 +45,11 @@
 typedef enum {
 	GO_LINE_INTERPOLATION_LINEAR,
 	GO_LINE_INTERPOLATION_SPLINE,
+	GO_LINE_INTERPOLATION_CLOSED_SPLINE,
+	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_STEP_START,
 	GO_LINE_INTERPOLATION_STEP_END,
 	GO_LINE_INTERPOLATION_STEP_CENTER_X,
@@ -67,6 +72,9 @@
 
 GOLineInterpolation	 go_line_interpolation_from_str		(char const *name);
 char const 		*go_line_interpolation_as_str		(GOLineInterpolation type);
+char const 		*go_line_interpolation_as_label		(GOLineInterpolation type);
+gboolean		 go_line_interpolation_supports_radial  (GOLineInterpolation type);
+gboolean		 go_line_interpolation_auto_skip	(GOLineInterpolation type);
 
 G_END_DECLS
 

Modified: trunk/plugins/plot_radar/gog-radar.c
==============================================================================
--- trunk/plugins/plot_radar/gog-radar.c	(original)
+++ trunk/plugins/plot_radar/gog-radar.c	Tue Nov 11 09:58:27 2008
@@ -504,7 +504,8 @@
 			path = next_path;
 		else
 			path = gog_chart_map_make_path (chart_map, c_vals,r_vals, series->base.num_elements,
-							series->base.interpolation);
+							series->base.interpolation,
+							series->base.interpolation_skip_invalid, NULL);
 
 		next_path = NULL;
 
@@ -512,7 +513,9 @@
 			go_path_close (path);
 			gog_renderer_fill_serie (view->renderer, path, NULL);
 		} else {
-			if (series->base.fill_type != GOG_SERIES_FILL_TYPE_NEXT) {
+			if (series->base.interpolation == GO_LINE_INTERPOLATION_CLOSED_SPLINE)
+				gog_renderer_fill_serie	(view->renderer, path, NULL);
+			else if (series->base.fill_type != GOG_SERIES_FILL_TYPE_NEXT) {
 				GOPath *close_path;
 
 				close_path = gog_chart_map_make_close_path (chart_map, c_vals, r_vals,
@@ -539,7 +542,8 @@
 
 						next_path = gog_chart_map_make_path
 							(chart_map, next_x_vals, next_y_vals,
-							 next_n_points, next_series->base.interpolation);
+							 next_n_points, next_series->base.interpolation,
+							 series->base.interpolation_skip_invalid, NULL);
 
 					}
 				}

Modified: trunk/plugins/plot_xy/gog-xy.c
==============================================================================
--- trunk/plugins/plot_xy/gog-xy.c	(original)
+++ trunk/plugins/plot_xy/gog-xy.c	Tue Nov 11 09:58:27 2008
@@ -960,11 +960,15 @@
 				path = next_path;
 			else
 				path = gog_chart_map_make_path (chart_map, x_vals, y_vals,
-								n, series->base.interpolation);
+								n, series->base.interpolation,
+								series->base.interpolation_skip_invalid,
+								&series->clamped_derivs);
 
 			next_path = NULL;
 
-			if (series->base.fill_type != GOG_SERIES_FILL_TYPE_NEXT) {
+			if (series->base.interpolation == GO_LINE_INTERPOLATION_CLOSED_SPLINE)
+				gog_renderer_fill_serie	(view->renderer, path, NULL);
+			else if (series->base.fill_type != GOG_SERIES_FILL_TYPE_NEXT) {
 				GOPath *close_path;
 
 				close_path = gog_chart_map_make_close_path (chart_map, x_vals, y_vals, n,
@@ -990,7 +994,9 @@
 
 						next_path = gog_chart_map_make_path
 							(chart_map, next_x_vals, next_y_vals,
-							 next_n_points, next_series->base.interpolation);
+							 next_n_points, next_series->base.interpolation,
+							 series->base.interpolation_skip_invalid,
+							 &series->clamped_derivs);
 
 					}
 				}

Modified: trunk/plugins/plot_xy/gog-xy.h
==============================================================================
--- trunk/plugins/plot_xy/gog-xy.h	(original)
+++ trunk/plugins/plot_xy/gog-xy.h	Tue Nov 11 09:58:27 2008
@@ -92,8 +92,9 @@
 	GogErrorBar 	  *x_errors;
 	GogErrorBar 	  *y_errors;
 	GogObject 	  *hdroplines;
-       	GogObject	  *vdroplines;
+    GogObject	  *vdroplines;
 	gboolean 	   invalid_as_zero;
+	double		   clamped_derivs[2]; /* start and and slopes for clamped cubic splines */
 } 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]