[gnumeric] ODF: regression line import/export



commit e23da0dfb3bbb4e398381e925c68e2271c2d8560
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Thu Aug 26 11:09:17 2010 -0600

    ODF: regression line import/export
    
    2010-08-25  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-read.c (od_style_prop_chart); new properties
    	(od_series_regression): new
    	(opendoc_content_dtd): connect od_series_regression
    	* openoffice-write.c (odf_write_standard_series): write regression
    	(odf_write_plot_style_uint): new
    	(odf_write_standard_axes_styles): remove unused varaible
    	(odf_write_*_reg): new
    	(odf_fill_chart_props_hash): add various regression method objects

 NEWS                                  |    4 +-
 plugins/openoffice/ChangeLog          |   11 +++
 plugins/openoffice/openoffice-read.c  |   75 +++++++++++++++++++++
 plugins/openoffice/openoffice-write.c |  114 ++++++++++++++++++++++++++++++++-
 4 files changed, 199 insertions(+), 5 deletions(-)
---
diff --git a/NEWS b/NEWS
index 3801324..9187289 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,7 @@
 Gnumeric 1.10.10
 
 Andreas:
-	* Export and import chart titles and subtitles to and from ODF.
-	* Some chart export and import to and from ODF fixes.
-	* Handle grids, dashes etc. in the ODF import/export.
+	* Significantly improve chart export and import to/from ODF.
 	* Improve handling of corrupted ODF files.
 	* Fix percentage style import from ODF. [#627517]
 	* Fix INTERPOLATION documentation. [#627461]
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 2ccdb75..d2e3e4a 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,5 +1,16 @@
 2010-08-25  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* openoffice-read.c (od_style_prop_chart); new properties
+	(od_series_regression): new
+	(opendoc_content_dtd): connect od_series_regression
+	* openoffice-write.c (odf_write_standard_series): write regression
+	(odf_write_plot_style_uint): new
+	(odf_write_standard_axes_styles): remove unused varaible
+	(odf_write_*_reg): new
+	(odf_fill_chart_props_hash): add various regression method objects
+
+2010-08-25  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* openoffice-read.c (oo_prop_list_apply_to_axis): new
 	(od_style_prop_chart): new attributes
 	(oo_chart_axis): call oo_prop_list_apply_to_axis instead of
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index fc3c9b5..dae3542 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -3680,6 +3680,22 @@ od_style_prop_chart (GsfXMLIn *xin, xmlChar const **attrs)
 			style->style_props = g_slist_prepend
 				(style->style_props,
 				 oo_prop_new_int ("font-gravity-pango", tmp));
+		else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, 
+					     "regression-type"))
+			style->other_props = g_slist_prepend
+				(style->other_props,
+				 oo_prop_new_string ("regression-type",
+						     CXML2C(attrs[1])));
+		else if (oo_attr_int_range (xin, attrs, OO_GNUM_NS_EXT, 
+					      "regression-polynomial-dims", &tmp, 
+					      1, 100))
+			style->other_props = g_slist_prepend
+				(style->other_props,
+				 oo_prop_new_int ("dims", tmp));
+		else if (oo_attr_bool (xin, attrs, OO_GNUM_NS_EXT, "regression-affine", 
+				       &btmp))
+			style->other_props = g_slist_prepend (style->other_props,
+				oo_prop_new_bool ("regression-affine", btmp));
 
 	}
 
@@ -4760,6 +4776,64 @@ oo_series_pt (GsfXMLIn *xin, xmlChar const **attrs)
 }
 
 static void
+od_series_regression (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	OOParseState *state = (OOParseState *)xin->user_state;
+	char const *style_name = NULL;
+
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, "style-name"))
+			style_name = CXML2C (attrs[1]);
+	if (style_name != NULL) {
+		GSList *l;
+		OOChartStyle *chart_style = g_hash_table_lookup
+			(state->chart.graph_styles, style_name);
+		GOStyle *style = NULL;
+		GogObject *regression;
+		gchar const *type_name = "GogLinRegCurve";
+		
+		for (l = chart_style->other_props; l != NULL; l = l->next) {
+			OOProp *prop = l->data;
+			if (0 == strcmp ("regression-type", prop->name)) {
+				char const *reg_type = g_value_get_string (&prop->value);
+				if (0 == strcmp (reg_type, "linear")) 
+					type_name = "GogLinRegCurve";
+				else if (0 == strcmp (reg_type, "power")) 
+					type_name = "GogPowerRegCurve";
+				else if (0 == strcmp (reg_type, "exponential")) 
+					type_name = "GogExpRegCurve";
+				else if (0 == strcmp (reg_type, "logarithmic")) 
+					type_name = "GogLogRegCurve";
+				else if (0 == strcmp 
+					 (reg_type, "gnm:exponential-smoothing"))
+					type_name = "GogExpSmooth";
+				else if (0 == strcmp 
+					 (reg_type, "gnm:logfit")) 
+					type_name = "GogLogFitCurve";
+				else if (0 == strcmp 
+					 (reg_type, "gnm:polynomial")) 
+					type_name = "GogPolynomRegCurve";
+				else if (0 == strcmp 
+					 (reg_type, "gnm:moving-average")) 
+					type_name = "GogMovingAvg";
+			}
+		}
+		
+		regression = GOG_OBJECT (gog_trend_line_new_by_name (type_name));
+		regression = gog_object_add_by_name (GOG_OBJECT (state->chart.series), 
+						     "Regression curve", regression);
+		oo_prop_list_apply (chart_style->other_props, G_OBJECT (regression));
+
+		g_object_get (G_OBJECT (regression), "style", &style, NULL);
+		if (style != NULL) {
+			odf_apply_style_props (chart_style->style_props, style);
+			g_object_unref (style);			
+		}
+	}	
+}
+
+
+static void
 oo_series_droplines (GsfXMLIn *xin, xmlChar const **attrs)
 {
 	OOParseState *state = (OOParseState *)xin->user_state;
@@ -5339,6 +5413,7 @@ static GsfXMLInNode const opendoc_content_dtd [] =
 		  GSF_XML_IN_NODE (CHART_SERIES, SERIES_DOMAIN, OO_NS_CHART, "domain", GSF_XML_NO_CONTENT, &oo_series_domain, NULL),
 		  GSF_XML_IN_NODE (CHART_SERIES, SERIES_DATA_PT, OO_NS_CHART, "data-point", GSF_XML_NO_CONTENT, &oo_series_pt, NULL),
 		  GSF_XML_IN_NODE (CHART_SERIES, SERIES_DATA_ERR, OO_NS_CHART, "error-indicator", GSF_XML_NO_CONTENT, NULL, NULL),
+		  GSF_XML_IN_NODE (CHART_SERIES, SERIES_REGRESSION, OO_NS_CHART, "regression-curve", GSF_XML_NO_CONTENT,  &od_series_regression, NULL),
 		  GSF_XML_IN_NODE (CHART_SERIES, SERIES_DROPLINES, OO_GNUM_NS_EXT, "droplines", GSF_XML_NO_CONTENT, &oo_series_droplines, NULL),
 		GSF_XML_IN_NODE (CHART_PLOT_AREA, CHART_WALL, OO_NS_CHART, "wall", GSF_XML_NO_CONTENT, &oo_chart_wall, NULL),
 		GSF_XML_IN_NODE (CHART_PLOT_AREA, CHART_FLOOR, OO_NS_CHART, "floor", GSF_XML_NO_CONTENT, NULL, NULL),
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index 245d853..2ce7b4e 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -3559,6 +3559,10 @@ odf_write_standard_series (GnmOOExport *state, GSList const *series)
 		if (NULL != dat) {
 			GnmExprTop const *texpr = gnm_go_data_get_expr (dat);
 			if (NULL != texpr) {
+				GogObjectRole const *role = 
+					gog_object_find_role_by_name 
+					(GOG_OBJECT (series->data), "Regression curve");
+
 				char *str = gnm_expr_top_as_string (texpr, &pp, state->conv);
 				GOData const *cat = gog_dataset_get_dim (GOG_DATASET (series->data), 
 									 GOG_MS_DIM_LABELS);
@@ -3585,6 +3589,21 @@ odf_write_standard_series (GnmOOExport *state, GSList const *series)
 					}
 				}
 
+				
+				if (role != NULL) {
+					GSList *l, *regressions = gog_object_get_children 
+						(GOG_OBJECT (series->data), role);
+					for (l = regressions; l != NULL && l->data != NULL; l = l->next) {
+						GogObject const *regression = l->data;
+						str = odf_get_gog_style_name_from_obj 
+							(GOG_OBJECT (regression));
+						gsf_xml_out_start_element (state->xml, CHART "regression-curve");
+						gsf_xml_out_add_cstr (state->xml, CHART "style-name", str);
+						gsf_xml_out_end_element (state->xml); /* </chart:regression-curve> */
+						g_free (str);
+					}
+				}
+
 				if (state->with_extension) {
 					odf_write_drop_line (state, GOG_OBJECT (series->data), 
 							     "Horizontal drop lines", FALSE);
@@ -3771,6 +3790,21 @@ odf_write_plot_style_int (GsfXMLOut *xml, GogObject const *plot,
 }
 
 static void
+odf_write_plot_style_uint (GsfXMLOut *xml, GogObject const *plot, 
+			  GObjectClass *klass, char const *property,
+			  char const *id)
+{
+	GParamSpec *spec;
+	if (NULL != (spec = g_object_class_find_property (klass, property)) 
+	    && spec->value_type == G_TYPE_UINT 
+	    && (G_PARAM_READABLE & spec->flags)) {
+		unsigned int i;
+		g_object_get (G_OBJECT (plot), property, &i, NULL);
+		gsf_xml_out_add_uint (xml, id, i);
+	}	
+}
+
+static void
 odf_write_plot_style_double (GsfXMLOut *xml, GogObject const *plot, 
 			     GObjectClass *klass, char const *property,
 			     char const *id)
@@ -4152,7 +4186,6 @@ odf_write_standard_axes_styles (GnmOOExport *state, GogObject const *chart,
 				gchar **z_style)
 {
 	GogObject const *axis;
-	GObjectClass *klass = G_OBJECT_GET_CLASS (G_OBJECT (plot));
 
 	axis = gog_object_get_child_by_name (chart, "X-Axis");
 	if (axis != NULL)
@@ -4927,6 +4960,75 @@ odf_write_drop(GnmOOExport *state, GOStyle const *style, GogObject const *obj)
 	odf_add_bool (state->xml, CHART "vertical", vertical);
 }
 
+static void
+odf_write_lin_reg(GnmOOExport *state, GOStyle const *style, GogObject const *obj) 
+{
+	gsf_xml_out_add_cstr (state->xml, CHART "regression-type",  "linear");
+	if (state->with_extension) {
+		GObjectClass *klass = G_OBJECT_GET_CLASS (G_OBJECT (obj));
+		odf_write_plot_style_bool (state->xml, obj, klass,
+					  "affine", GNMSTYLE "regression-affine");
+		odf_write_plot_style_uint (state->xml, obj, klass,
+					  "dims", GNMSTYLE "regression-polynomial-dims");
+	}
+}
+
+static void
+odf_write_polynom_reg(GnmOOExport *state, GOStyle const *style, GogObject const *obj) 
+{
+	if (state->with_extension) {
+		GObjectClass *klass = G_OBJECT_GET_CLASS (G_OBJECT (obj));
+		
+		gsf_xml_out_add_cstr (state->xml, CHART "regression-type", 
+				      GNMSTYLE "polynomial");
+		odf_write_plot_style_uint (state->xml, obj, klass,
+					  "dims", GNMSTYLE "regression-polynomial-dims");
+		odf_write_plot_style_bool (state->xml, obj, klass,
+					  "affine", GNMSTYLE "regression-affine");
+	}
+}
+
+static void
+odf_write_exp_reg(GnmOOExport *state, GOStyle const *style, GogObject const *obj) 
+{
+	gsf_xml_out_add_cstr (state->xml, CHART "regression-type",  "exponential");
+}
+
+static void
+odf_write_power_reg(GnmOOExport *state, GOStyle const *style, GogObject const *obj) 
+{
+	gsf_xml_out_add_cstr (state->xml, CHART "regression-type",  "power");
+}
+
+static void
+odf_write_log_reg(GnmOOExport *state, GOStyle const *style, GogObject const *obj) 
+{
+	gsf_xml_out_add_cstr (state->xml, CHART "regression-type",  "logarithmic");
+}
+
+static void
+odf_write_log_fit_reg(GnmOOExport *state, GOStyle const *style, GogObject const *obj) 
+{
+	if (state->with_extension)
+		gsf_xml_out_add_cstr (state->xml, CHART "regression-type", 
+				      GNMSTYLE "log-fit");
+}
+
+static void
+odf_write_movig_avg_reg(GnmOOExport *state, GOStyle const *style, GogObject const *obj) 
+{
+	if (state->with_extension)
+		gsf_xml_out_add_cstr (state->xml, CHART "regression-type", 
+				      GNMSTYLE "moving-average");
+}
+
+static void
+odf_write_exp_smooth_reg(GnmOOExport *state, GOStyle const *style, GogObject const *obj) 
+{
+	if (state->with_extension)
+		gsf_xml_out_add_cstr (state->xml, CHART "regression-type", 
+				      GNMSTYLE "exponential-smoothed");
+}
 
 static void
 odf_fill_chart_props_hash (GnmOOExport *state)
@@ -4939,7 +5041,15 @@ odf_fill_chart_props_hash (GnmOOExport *state)
 					    GogObject const *obj);
 	} props[] = {
 		{"GogSeriesLines", odf_write_drop},
-		{"GogAxis", odf_write_axis_style}
+		{"GogAxis", odf_write_axis_style},
+		{"GogLinRegCurve", odf_write_lin_reg},
+		{"GogPolynomRegCurve", odf_write_polynom_reg},
+		{"GogExpRegCurve", odf_write_exp_reg},
+		{"GogPowerRegCurve", odf_write_power_reg},
+		{"GogLogRegCurve", odf_write_log_reg},
+		{"GogLogFitCurve", odf_write_log_fit_reg},
+		{"GogMovingAvg", odf_write_movig_avg_reg},
+		{"GogExpSmooth", odf_write_exp_smooth_reg},
 	};
 		
 	for (i = 0 ; i < (int)G_N_ELEMENTS (props) ; i++)



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