[gnumeric] Extracted chart/drawing xlsx code to new files.



commit 5899fbd8a3d3e81c7ba3c5d7f3acf5e4fcd7f55f
Author: Jean Brefort <jean brefort normalesup org>
Date:   Sat Mar 12 11:10:22 2011 +0100

    Extracted chart/drawing xlsx code to new files.

 plugins/excel/ChangeLog            |    8 +
 plugins/excel/Makefile.am          |    4 +-
 plugins/excel/xlsx-read-drawing.c  | 1824 ++++++++++++++++++++++++++++++++++++
 plugins/excel/xlsx-read.c          | 1572 +------------------------------
 plugins/excel/xlsx-write-drawing.c |  541 +++++++++++
 plugins/excel/xlsx-write.c         |  409 +--------
 6 files changed, 2390 insertions(+), 1968 deletions(-)
---
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 84a2807..61f3b42 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,3 +1,11 @@
+2011-03-12  Jean Brefort  <jean brefort normalesup org>
+
+	* Makefile.am: add new xlsx drawing/chart files.
+	* xlsx-read-drawing.c: new file, better import of styles.
+	* xlsx-read.c: moved drawing/chart code to xlsx-read-drawing.c.
+	* xlsx-write-drawing.c: new file with enhanced chart export.
+	* xlsx-write.c: moved drawing/chart code to xlsx-write-drawing.c.
+
 2011-03-05  Jean Brefort  <jean brefort normalesup org>
 
 	* xlsx-read.c (xlsx_chart_ser_f), (xlsx_chart_text_start),
diff --git a/plugins/excel/Makefile.am b/plugins/excel/Makefile.am
index 97691bb..d46d004 100644
--- a/plugins/excel/Makefile.am
+++ b/plugins/excel/Makefile.am
@@ -80,6 +80,8 @@ xml_DATA = $(xml_in_files:.xml.in=.xml)
 
 EXTRA_DIST = $(xml_in_files)	\
 	xlsx-read-pivot.c	\
-	xlsx-write-pivot.c
+	xlsx-write-pivot.c	\
+	xlsx-read-drawing.c	\
+	xlsx-write-drawing.c
 
 DISTCLEANFILES = $(xml_DATA)
diff --git a/plugins/excel/xlsx-read-drawing.c b/plugins/excel/xlsx-read-drawing.c
new file mode 100644
index 0000000..9a8960b
--- /dev/null
+++ b/plugins/excel/xlsx-read-drawing.c
@@ -0,0 +1,1824 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * xlsx-drawing-read.c : import MS Office Open xlsx drawings and charts.
+ *
+ * Copyright (C) 2006-2007 Jody Goldberg (jody gnome org)
+ * Copyright (C) 2011 Jean Brefort (jean brefort normalesup org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+ * USA
+ */
+
+/*****************************************************************************/
+
+static void
+xlsx_chart_push_obj (XLSXReadState *state, GogObject *obj)
+{
+	state->obj_stack = g_slist_prepend (state->obj_stack, state->cur_obj);
+	state->cur_obj = obj;
+
+#if 0
+	g_print ("push %s\n", G_OBJECT_TYPE_NAME (obj));
+#endif
+}
+
+static void
+xlsx_chart_pop_obj (XLSXReadState *state)
+{
+	GSList *obj_stack = state->obj_stack;
+	g_return_if_fail (obj_stack != NULL);
+
+#if 0
+	g_print ("push %s\n", G_OBJECT_TYPE_NAME (state->cur_obj));
+#endif
+
+	state->cur_obj = obj_stack->data;
+	state->obj_stack = g_slist_remove (state->obj_stack, state->cur_obj);
+}
+
+static void
+xlsx_chart_add_plot (GsfXMLIn *xin, char const *type)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	if (NULL != (state->plot = (GogPlot*) gog_plot_new_by_name (type)))
+		/* Add _before_ setting styles so theme does not override */
+		gog_object_add_by_name (GOG_OBJECT (state->chart),
+			"Plot", GOG_OBJECT (state->plot));
+}
+
+/* shared with pie of pie, and bar of pie */
+static void
+xlsx_vary_colors (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	int vary;
+	if (simple_bool (xin, attrs, &vary))
+		g_object_set (G_OBJECT (state->plot),
+			"vary-style-by-element", vary, NULL);
+}
+
+static void
+xlsx_chart_pie_sep (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	int sep;
+	if (simple_int (xin, attrs, &sep))
+		g_object_set (G_OBJECT (state->plot),
+			"default-separation", (double)(CLAMP (sep, 0, 500))/ 100., NULL);
+}
+
+/* shared with pie of pie, and bar of pie */
+static void xlsx_chart_pie (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogPiePlot"); }
+static void xlsx_chart_ring (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogRingPlot"); }
+
+/***********************************************************************/
+
+static void
+xlsx_chart_bar_dir (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	static EnumVal const dirs[] = {
+		{ "bar",	 TRUE },
+		{ "col",	 FALSE },
+		{ NULL, 0 }
+	};
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	int dir;
+
+	g_return_if_fail (state->plot != NULL);
+
+	if (simple_enum (xin, attrs, dirs, &dir))
+		g_object_set (G_OBJECT (state->plot), "horizontal", dir, NULL);
+}
+
+static void
+xlsx_chart_bar_overlap (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	int overlap;
+	g_return_if_fail (state->plot != NULL);
+	if (simple_int (xin, attrs, &overlap))
+		g_object_set (G_OBJECT (state->plot),
+			"overlap-percentage", CLAMP (overlap, -100, 100), NULL);
+}
+static void
+xlsx_chart_bar_group (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	char const *type = "normal";
+
+	g_return_if_fail (state->plot != NULL);
+
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (0 == strcmp (attrs[0], "val")) {
+			if (0 == strcmp (attrs[1], "percentStacked"))
+				type = "as_percentage";
+			else if (0 == strcmp (attrs[1], "stacked"))
+				type = "stacked";
+			g_object_set (G_OBJECT (state->plot), "type", type, NULL);
+		}
+}
+static void
+xlsx_chart_bar_gap (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	int gap;
+	if (simple_int (xin, attrs, &gap))
+		g_object_set (G_OBJECT (state->plot),
+			"gap-percentage", CLAMP (gap, 0, 500), NULL);
+}
+
+static void
+xlsx_chart_bar (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	xlsx_chart_add_plot (xin, "GogBarColPlot");
+}
+
+/***********************************************************************/
+
+static void
+xlsx_axis_info_free (XLSXAxisInfo *info)
+{
+	g_free (info->id);
+	g_free (info->cross_id);
+	if (NULL != info->axis)
+		g_object_unref (info->axis);
+	g_free (info);
+}
+
+static void
+xlsx_plot_axis_id (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	if (NULL == state->plot)
+		return;
+
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (0 == strcmp (attrs[0], "val")) {
+			XLSXAxisInfo *res = g_hash_table_lookup (state->axis.by_id, attrs[1]);
+			if (NULL == res) {
+				res = g_new0 (XLSXAxisInfo, 1);
+				res->id = g_strdup (attrs[1]);
+				res->axis	= NULL;
+				res->plots	= NULL;
+				res->type	= XLSX_AXIS_UNKNOWN;
+				res->compass	= GOG_POSITION_AUTO;
+				res->cross	= GOG_AXIS_CROSS;
+				res->cross_value = go_nan;
+				g_hash_table_replace (state->axis.by_id, res->id, res);
+#ifdef DEBUG_AXIS
+				g_print ("create %s = %p\n", attrs[1], res);
+#endif
+			}
+#ifdef DEBUG_AXIS
+			g_print ("add plot %p to %p\n", state->plot, res);
+#endif
+			res->plots = g_slist_prepend (res->plots, state->plot);
+		}
+}
+
+static void
+xlsx_axis_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	state->axis.obj	 = g_object_new (GOG_TYPE_AXIS, NULL);
+	state->axis.type = xin->node->user_data.v_int;
+	state->axis.info = NULL;
+	xlsx_chart_push_obj (state, GOG_OBJECT (state->axis.obj));
+}
+
+static void
+xlsx_axis_crosses_at (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	/* This element specifies where on the axis the perpendicular axis crosses. 
+	   The units are dependent on the type of axis.
+	   When specified as a child element of valAx, the value is a decimal number on the value axis. When specified as a
+	   child element of dateAx, the date is defined as a integer number of days relative to the base date of the current
+	   date base. When specified as a child element of catAx, the value is an integer category number, starting with 1
+	   as the first category.
+	*/
+ 	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+
+	simple_float (xin, attrs, &state->axis.info->cross_value);
+}
+
+static void
+xlsx_axis_id (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (0 == strcmp (attrs[0], "val")) {
+			state->axis.info = g_hash_table_lookup (state->axis.by_id, attrs[1]);
+			if (NULL != state->axis.info) {
+				g_return_if_fail (state->axis.info->axis == NULL);
+				state->axis.info->axis = state->axis.obj;
+				g_hash_table_replace (state->axis.by_obj,
+					state->axis.obj, state->axis.info);
+			}
+#ifdef DEBUG_AXIS
+			g_print ("define %s = %p\n", attrs[1], state->axis.info);
+#endif
+		}
+}
+
+static void
+xlsx_axis_delete (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	int del = 0;
+	if (state->axis.info && simple_bool (xin, attrs, &del))
+		state->axis.info->deleted = del;
+	if (state->axis.info && del)
+		g_object_set (state->axis.info->axis, "invisible", TRUE, NULL);
+}
+static void
+xlsx_axis_orientation (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	static EnumVal const orients[] = {
+		{ "minMax",	 FALSE },
+		{ "maxMin",	 TRUE },
+		{ NULL, 0 }
+	};
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	int orient;
+	if (state->axis.info && simple_enum (xin, attrs, orients, &orient))
+		g_object_set (G_OBJECT (state->axis.obj),
+			"invert-axis", orient, NULL);
+}
+static void
+xlsx_chart_logbase (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	int base;
+	if (state->axis.info && simple_int (xin, attrs, &base))
+		g_object_set (G_OBJECT (state->axis.obj),
+			"map-name", "Log", NULL);
+}
+static void
+xlsx_axis_pos (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	static EnumVal const positions[] = {
+		{ "t",	 GOG_POSITION_N },
+		{ "b",	 GOG_POSITION_S },
+		{ "l",	 GOG_POSITION_W },
+		{ "r",	 GOG_POSITION_E },
+		{ NULL, 0 }
+	};
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	int position;
+#ifdef DEBUG_AXIS
+	g_print ("SET POS %s for %p\n", attrs[1],  state->axis.info);
+#endif
+	if (state->axis.info && simple_enum (xin, attrs, positions, &position))
+		state->axis.info->compass = position;
+}
+
+static void
+xlsx_axis_bound (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	gnm_float val;
+	if (state->axis.info && simple_float (xin, attrs, &val))
+		gog_dataset_set_dim (GOG_DATASET (state->axis.obj),
+			xin->node->user_data.v_int,
+			go_data_scalar_val_new (val), NULL);
+}
+
+static void
+xlsx_axis_crosses (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	static EnumVal const crosses[] = {
+		{ "autoZero",	GOG_AXIS_CROSS },
+		{ "max",	GOG_AXIS_AT_HIGH },
+		{ "min",	GOG_AXIS_AT_LOW },
+		{ NULL, 0 }
+	};
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	int cross;
+
+	if (state->axis.info && simple_enum (xin, attrs, crosses, &cross))
+		state->axis.info->cross = cross;
+}
+
+static void
+xlsx_axis_crossax (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	if (state->axis.info && !strcmp ((char const*) attrs[0], "val"))
+		state->axis.info->cross_id = g_strdup (attrs[1]);
+}
+
+static void
+xlsx_chart_gridlines (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->axis.obj) {
+		GogObject *grid = gog_object_add_by_name (
+			GOG_OBJECT (state->axis.obj), "MajorGrid", NULL);
+		xlsx_chart_push_obj (state, grid);
+	}
+}
+
+static void
+xlsx_axis_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+
+	/* Try to guess what type of axis to use */
+	if (NULL != state->axis.info) {
+		GogPlot *plot = state->axis.info->plots->data; /* just use the first */
+		char const *type = G_OBJECT_TYPE_NAME (plot);
+		char const *role = NULL;
+		GSList *ptr;
+
+		if (0 == strcmp (type, "GogRadarPlot") ||
+		    0 == strcmp (type, "GogRadarAreaPlot")) {
+			role = (state->axis.type == XLSX_AXIS_CAT
+				|| state->axis.type == XLSX_AXIS_DATE) ? "Radial-Axis" : "Circular-Axis";
+		} else if (0 == strcmp (type, "GogBubblePlot") ||
+			   0 == strcmp (type, "GogXYPlot")) {
+			/* both are VAL, use the position to decide */
+			if (state->axis.info->compass  == GOG_POSITION_N ||
+			    state->axis.info->compass  == GOG_POSITION_S)
+				role = "X-Axis";
+			else
+				role = "Y-Axis";
+		} else if (0 == strcmp (type, "GogBarColPlot")) {
+			gboolean h;
+			/* swap for bar plots */
+			g_object_get (G_OBJECT (plot), "horizontal", &h, NULL);
+			if (h)
+				role = (state->axis.type == XLSX_AXIS_CAT
+				        || state->axis.type == XLSX_AXIS_DATE) ? "Y-Axis" : "X-Axis";
+		}
+
+		if (NULL == role)
+			role = (state->axis.type == XLSX_AXIS_CAT
+				|| state->axis.type == XLSX_AXIS_DATE) ? "X-Axis" : "Y-Axis";
+
+		/* absorb a ref, and set the id, and atype */
+		gog_object_add_by_name (GOG_OBJECT (state->chart),
+			role, GOG_OBJECT (state->axis.obj));
+		g_object_ref (G_OBJECT (state->axis.obj));
+		for (ptr = state->axis.info->plots; ptr != NULL ; ptr = ptr->next) {
+#ifdef DEBUG_AXIS
+			g_print ("connect plot %p to %p in role %s\n", ptr->data, state->axis.obj, role);
+#endif
+			gog_plot_set_axis (ptr->data, state->axis.obj);
+		}
+
+		state->axis.obj  = NULL;
+		state->axis.info = NULL;
+	}
+
+	xlsx_chart_pop_obj (state);
+	state->axis.info = NULL;
+}
+
+static void xlsx_chart_area (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogAreaPlot"); }
+static void xlsx_chart_line (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogLinePlot"); }
+
+static void
+xlsx_chart_xy (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	xlsx_chart_add_plot (xin, "GogXYPlot");
+	g_object_set (G_OBJECT (state->plot), "default-style-has-fill", FALSE, NULL);
+}
+
+static void
+xlsx_scatter_style (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	static EnumVal styles[] = {
+		{"line",	0},
+		{"lineMarker",  1},
+		{"marker",      2},
+		{"none",	3},
+		{"smooth",      4},
+		{"smoothMarker", 5}
+	};
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	int style;
+
+	if (simple_enum (xin, attrs, styles, &style))
+		switch (style) {
+		case 0:
+			g_object_set (G_OBJECT (state->plot),
+			              "default-style-has-markers", FALSE,
+			              NULL);
+			break;
+		case 2:
+			g_object_set (G_OBJECT (state->plot),
+			              "default-style-has-lines", FALSE,
+			              NULL);
+			break;
+		case 3:
+			g_object_set (G_OBJECT (state->plot),
+			              "default-style-has-markers", FALSE,
+			              "default-style-has-lines", FALSE,
+			              NULL);
+			break;
+		case 4:
+			g_object_set (G_OBJECT (state->plot),
+			              "use-splines", TRUE,
+			              "default-style-has-markers", FALSE, NULL);
+			break;
+		case 5:
+			g_object_set (G_OBJECT (state->plot),
+			              "use-splines", TRUE,
+			              NULL);
+			break;
+		}
+}
+
+static void xlsx_chart_bubble (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogBubblePlot"); }
+static void xlsx_chart_radar (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogRadarPlot"); }
+#if 0
+	char const *type = "GogRadarPlot";
+	gboolean with_markers = FALSE;
+	/* Irritants.  They put the sub type into a child record ... */
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (0 == strcmp (attrs[0], "type")) {
+			if (0 == strcmp (attrs[1], "filled"))
+				type = "as_percentage";
+			else if (0 == strcmp (attrs[1], "marker"))
+				type = "stacked";
+			g_object_set (G_OBJECT (state->plot), "type", type, NULL);
+		}
+		if (0 == strcmp (xin, attrs, "cx", state->drawing_pos + (COL | TO | OFFSET)))
+			state->drawing_pos_flags |= (1 << (COL | TO | OFFSET));
+	g_object_set (G_OBJECT (state->plot), "default-style-has-markers", with_markers, NULL);
+#endif
+
+static void
+xlsx_plot_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	state->plot = NULL;
+}
+
+static void
+xlsx_chart_ser_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->plot) {
+		state->series = gog_plot_new_series (state->plot);
+		xlsx_chart_push_obj (state, GOG_OBJECT (state->series));
+	}
+}
+static void
+xlsx_chart_ser_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->series) {
+		xlsx_chart_pop_obj (state);
+		state->series = NULL;
+	}
+}
+
+#warning shared from ms-chart.c for now, move to GOffice with the enum
+extern void XL_gog_series_set_dim (GogSeries *series, GogMSDimType ms_type, GOData *val);
+static void
+xlsx_chart_ser_f (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->series) {
+		GnmParsePos pp;
+		GnmExprTop const *texpr = xlsx_parse_expr (xin, xin->content->str,
+			parse_pos_init_sheet (&pp, state->sheet));
+
+		XL_gog_series_set_dim (state->series, state->dim_type,
+			(state->dim_type != GOG_MS_DIM_LABELS)
+			? gnm_go_data_vector_new_expr (state->sheet, texpr)
+			: gnm_go_data_scalar_new_expr (state->sheet, texpr));
+	} else if (GOG_IS_LABEL (state->cur_obj)) {
+		GnmParsePos pp;
+		GnmExprTop const *texpr = xlsx_parse_expr (xin, xin->content->str,
+			parse_pos_init_sheet (&pp, state->sheet));
+
+		gog_dataset_set_dim (GOG_DATASET (state->cur_obj), 0,
+			gnm_go_data_scalar_new_expr (state->sheet, texpr), NULL);
+	}
+}
+
+static void
+xlsx_ser_type_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	state->dim_type = xin->node->user_data.v_int;
+}
+
+static void
+xlsx_ser_type_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	state->dim_type = GOG_MS_DIM_LABELS;
+}
+
+static void
+xlsx_chart_legend (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	gog_object_add_by_name (GOG_OBJECT (state->chart), "Legend", NULL);
+}
+
+static void
+xlsx_chart_pt_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->series) {
+		state->series_pt_has_index = FALSE;
+		state->series_pt = gog_object_add_by_name (
+			GOG_OBJECT (state->series), "Point", NULL);
+		xlsx_chart_push_obj (state, state->series_pt);
+	}
+}
+
+static void
+xlsx_chart_pt_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->series) {
+		xlsx_chart_pop_obj (state);
+		if (!state->series_pt_has_index) {
+			gog_object_clear_parent (state->series_pt);
+			g_object_unref (state->series_pt);
+		}
+		state->series_pt = NULL;
+	}
+}
+
+static void
+xlsx_chart_pt_index (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	int tmp;
+
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (attr_int (xin, attrs, "val", &tmp)) {
+			state->series_pt_has_index = TRUE;
+			g_object_set (state->series_pt, "index", tmp, NULL);
+		}
+}
+
+static void
+xlsx_chart_pt_sep (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	int sep;
+	if (simple_int (xin, attrs, &sep) &&
+	    g_object_class_find_property (G_OBJECT_GET_CLASS (state->series_pt), "separation"))
+		g_object_set (state->series_pt, "separation", (double)sep / 100., NULL);
+}
+
+static void
+xlsx_chart_style_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->cur_obj &&
+	    GOG_IS_STYLED_OBJECT (state->cur_obj) &&
+	    NULL == state->marker) {
+		g_return_if_fail (state->cur_style == NULL);
+		state->cur_style = go_style_dup (
+			go_styled_object_get_style (GO_STYLED_OBJECT (state->cur_obj)));
+	}
+}
+static void
+xlsx_chart_style_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+
+	if (NULL != state->cur_style) {
+		go_styled_object_set_style (GO_STYLED_OBJECT (state->cur_obj),
+			state->cur_style);
+		g_object_unref (state->cur_style);
+		state->cur_style = NULL;
+	}
+}
+static void
+xlsx_style_line_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	state->sp_type |= GO_STYLE_LINE;
+	state->gocolor = &state->cur_style->line.color;
+}
+
+static void
+xlsx_style_line_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	state->sp_type &= ~GO_STYLE_LINE;
+}
+
+static void
+xlsx_chart_no_fill (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->marker)
+		;
+	else if (NULL != state->cur_style) {
+		if (!(state->sp_type & GO_STYLE_LINE)) {
+			state->cur_style->fill.type = GO_STYLE_FILL_NONE;
+			state->cur_style->fill.auto_type = FALSE;
+		}
+	}
+}
+
+static void
+xlsx_chart_grad_fill (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->marker) /* do xlsx support gradients in markers */
+		;
+	else if (NULL != state->cur_style) {
+		if (!(state->sp_type & GO_STYLE_LINE)) {
+			state->cur_style->fill.type = GO_STYLE_FILL_GRADIENT;
+			state->cur_style->fill.auto_type = FALSE;
+		}
+	}
+}
+
+static void
+xlsx_chart_grad_linear (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	int ang;
+	g_return_if_fail (state->cur_style);
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (attr_int (xin, attrs, "ang", &ang)) {
+			ang = ((ang / 60000) + 22) / 45; /* now ang is between 0 and 8 */
+			switch (ang) {
+			case 1:
+				state->cur_style->fill.gradient.dir = GO_GRADIENT_NW_TO_SE;
+				break;
+			case 2:
+				state->cur_style->fill.gradient.dir = GO_GRADIENT_W_TO_E;
+				break;
+			case 3:
+				state->cur_style->fill.gradient.dir = GO_GRADIENT_SW_TO_NE;
+				break;
+			case 4:
+				state->cur_style->fill.gradient.dir = GO_GRADIENT_S_TO_N;
+				break;
+			case 5:
+				state->cur_style->fill.gradient.dir = GO_GRADIENT_SE_TO_NW;
+				break;
+			case 6:
+				state->cur_style->fill.gradient.dir = GO_GRADIENT_E_TO_W;
+				break;
+			case 7:
+				state->cur_style->fill.gradient.dir = GO_GRADIENT_NE_TO_SW;
+				break;
+			default:
+				state->cur_style->fill.gradient.dir = GO_GRADIENT_N_TO_S;
+				break;
+			}
+		}
+	/* FIXME: we do not support the "scaled" attribute */
+}
+
+static void
+xlsx_chart_grad_stop (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	int pos;
+	g_return_if_fail (state->cur_style);
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (attr_int (xin, attrs, "pos", &pos)) {
+			if (pos <= 50000) {
+				/* FIXME: use betstate->auto_colorter gradients 
+				 * for now, we only support stops at 0 and 1 */
+				state->gocolor = &state->cur_style->fill.pattern.back;
+				state->auto_color = &state->cur_style->fill.auto_back;
+			} else {
+				state->gocolor = &state->cur_style->fill.pattern.fore;
+				state->auto_color = &state->cur_style->fill.auto_fore;
+			}
+		}
+}
+
+static void
+xlsx_chart_solid_fill (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->marker) {
+		if (!(state->sp_type & GO_STYLE_LINE)) {
+			state->color_setter = (void (*) (gpointer data, GOColor color)) go_marker_set_fill_color;
+			state->color_data = state->marker;
+		} else {
+			state->color_setter = (void (*) (gpointer data, GOColor color)) go_marker_set_outline_color;
+			state->color_data = state->marker;
+		}
+	} else if (NULL != state->cur_style) {
+		if (!(state->sp_type & GO_STYLE_LINE)) {
+			state->cur_style->fill.type = GO_STYLE_FILL_PATTERN;
+			state->cur_style->fill.auto_type = FALSE;
+			state->gocolor = &state->cur_style->fill.pattern.back;
+			state->auto_color = &state->cur_style->fill.auto_back;
+		}
+	}
+}
+
+static void
+xlsx_draw_color_themed (GsfXMLIn *xin, xmlChar const **attrs)
+{
+#if 0
+	static EnumVal const colors[] = {
+		{ "bg1",	 0 }, /* Background Color 1 */
+		{ "tx1",	 1 }, /* Text Color 1 */
+		{ "bg2",	 2 }, /* Background Color 2 */
+		{ "tx2",	 3 }, /* Text Color 2 */
+		{ "accent1",	 4 }, /* Accent Color 1 */
+		{ "accent2",	 5 }, /* Accent Color 2 */
+		{ "accent3",	 6 }, /* Accent Color 3 */
+		{ "accent4",	 7 }, /* Accent Color 4 */
+		{ "accent5",	 8 }, /* Accent Color 5 */
+		{ "accent6",	 9 }, /* Accent Color 6 */
+		{ "hlink",	10 }, /* Hyperlink Color */
+		{ "folHlink",	11 }, /* Followed Hyperlink Color */
+		{ "phClr",	12 }, /* Style Color */
+		{ "dk1",	13 }, /* Dark Color 1 */
+		{ "lt1",	14 }, /* Light Color 1 */
+		{ "dk2",	15 }, /* Dark Color 2 */
+		{ "lt2",	16 }, /* Light Color 2 */
+		{ NULL, 0 }
+	};
+#endif
+
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	gpointer val = NULL;
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (0 == strcmp (attrs[0], "val")) {
+			val = g_hash_table_lookup (state->theme_colors_by_name, attrs[1]);
+			if (NULL == val)
+				xlsx_warning (xin, _("Unknown color '%s'"), attrs[1]);
+		}
+
+	*state->gocolor = GPOINTER_TO_UINT (val);
+}
+
+static void
+xlsx_draw_color_rgb (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (attr_gocolor (xin, attrs, "val", &state->color))
+			if (state->auto_color)
+				*state->auto_color = FALSE;
+}
+
+static void
+xlsx_draw_color_alpha (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	int val;
+	if (simple_int (xin, attrs, &val)) {
+		int level = 255 * val / 100000;
+		state->color = GO_COLOR_CHANGE_A (state->color, level);
+		if (state->auto_color)
+			state->auto_color = FALSE;
+	}
+}
+
+static void
+xlsx_draw_color_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	if (state->gocolor) {
+		*state->gocolor = state->color;
+		if (state->auto_color) {
+			*state->auto_color = FALSE;
+			state->auto_color = NULL;
+		}
+		state->gocolor = NULL;
+	} else if (state->color_setter) {
+		state->color_setter (state->color_data, state->color);
+		state->color_setter = NULL;
+	}
+}
+
+static void
+xlsx_draw_line_dash (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	static EnumVal const dashes[] = {
+		{ "solid",		GO_LINE_SOLID },
+		{ "dot",		GO_LINE_DOT },
+		{ "dash",		GO_LINE_DASH },
+		{ "lgDash",		GO_LINE_LONG_DASH },
+		{ "dashDot",		GO_LINE_DASH_DOT },
+		{ "lgDashDot",		GO_LINE_DASH_DOT_DOT },
+		{ "lgDashDotDot",	GO_LINE_DASH_DOT_DOT_DOT },
+		{ "sysDash",		GO_LINE_S_DASH },
+		{ "sysDot",		GO_LINE_S_DOT },
+		{ "sysDashDot",		GO_LINE_S_DASH_DOT },
+		{ "sysDashDotDot",	GO_LINE_S_DASH_DOT_DOT },
+		{ NULL, 0 }
+	};
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	int dash;
+
+	if (!simple_enum (xin, attrs, dashes, &dash))
+		return;
+
+	if (NULL != state->marker)
+		; /* what goes here ?*/
+	else if (NULL != state->cur_style) {
+		if (state->sp_type & GO_STYLE_LINE) {
+			state->cur_style->line.auto_dash = FALSE;
+			state->cur_style->line.dash_type = dash;
+		} else {
+			; /* what goes here ?*/
+		}
+	}
+}
+
+static void
+xlsx_chart_marker_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	state->marker = go_marker_new ();
+	state->marker_symbol = GO_MARKER_MAX;
+}
+
+static void
+xlsx_chart_marker_symbol (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	static EnumVal const symbols[] = {
+		{ "circle",	GO_MARKER_CIRCLE },
+		{ "dash",	GO_MARKER_BAR },		/* FIXME */
+		{ "diamond",	GO_MARKER_DIAMOND },
+		{ "dot",	GO_MARKER_HALF_BAR },		/* FIXME */
+		{ "none",	GO_MARKER_NONE },
+		{ "plus",	GO_MARKER_CROSS },		/* CHECK ME */
+		{ "square",	GO_MARKER_SQUARE },
+		{ "star",	GO_MARKER_ASTERISK },		/* CHECK ME */
+		{ "triangle",	GO_MARKER_TRIANGLE_UP },	/* FIXME */
+		{ "x",		GO_MARKER_X },
+		{ NULL, 0 }
+	};
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	int symbol;
+	if (NULL != state->marker && simple_enum (xin, attrs, symbols, &symbol))
+		state->marker_symbol = symbol;
+}
+
+static void
+xlsx_chart_marker_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->cur_obj && GOG_IS_STYLED_OBJECT (state->cur_obj)) {
+		GOStyle *style = go_styled_object_get_style (
+			GO_STYLED_OBJECT (state->cur_obj));
+		if (state->marker_symbol != GO_MARKER_MAX) {
+			style->marker.auto_shape = FALSE;
+			go_marker_set_shape (state->marker, state->marker_symbol);
+		}
+		go_style_set_marker (style, state->marker);
+		state->marker = NULL;
+	}
+}
+
+static void
+xlsx_chart_text_start (GsfXMLIn *xin, G_GNUC_UNUSED xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	if (NULL == state->series) { /* Hmm, why? */
+		GogObject *label = gog_object_add_by_name (state->cur_obj,
+			(state->cur_obj == (GogObject *)state->chart) ? "Title" : "Label", NULL);
+		xlsx_chart_push_obj (state, label);
+	}
+}
+
+static void
+xlsx_chart_text (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+
+	if (NULL == state->series) {
+		if (state->cur_obj && state->chart_tx) {
+			GnmValue *value = value_new_string_nocopy (state->chart_tx);
+			GnmExprTop const *texpr = gnm_expr_top_new_constant (value);
+			gog_dataset_set_dim (GOG_DATASET (state->cur_obj), 0,
+				gnm_go_data_scalar_new_expr (state->sheet, texpr), NULL);
+			state->chart_tx = NULL;
+		}
+		xlsx_chart_pop_obj (state);
+	}
+	g_free (state->chart_tx);
+	state->chart_tx = NULL;
+}
+
+static void
+xlsx_chart_p_start (GsfXMLIn *xin, G_GNUC_UNUSED xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	if (state->chart_tx) {
+		char *buf = g_strconcat (state->chart_tx, "\n", NULL);
+		g_free (state->chart_tx);
+		state->chart_tx = buf;
+	}
+}
+
+static void
+xlsx_chart_text_content (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	/* a rich node can contain several t children, if this happens, concatenate
+	 the contents */
+	if (state->chart_tx) {
+		char *buf = g_strconcat (state->chart_tx, xin->content->str, NULL);
+		g_free (state->chart_tx);
+		state->chart_tx = buf;
+	} else
+		state->chart_tx = g_strdup (xin->content->str);
+}
+
+static void
+xlsx_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState *state = (XLSXReadState *)xin->user_state;
+	GogObject *backplane = gog_object_add_by_name (
+		GOG_OBJECT (state->chart), "Backplane", NULL);
+	// set a transparent default background
+	GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (backplane));
+	style->fill.type = GO_STYLE_FILL_NONE;
+	style->fill.auto_type = FALSE;
+	xlsx_chart_push_obj (state, backplane);
+}
+static void
+xlsx_chart_pop (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	xlsx_chart_pop_obj ((XLSXReadState *)xin->user_state);
+}
+
+static GsfXMLInNode const xlsx_chart_dtd[] =
+{
+GSF_XML_IN_NODE_FULL (START, START, -1, NULL, GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
+GSF_XML_IN_NODE_FULL (START, CHART_SPACE, XL_NS_CHART, "chartSpace", GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
+  GSF_XML_IN_NODE (CHART_SPACE, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, &xlsx_chart_style_start, &xlsx_chart_style_end),
+    GSF_XML_IN_NODE (SHAPE_PR, SP_XFRM, XL_NS_DRAW, "xfrm", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (SP_XFRM, SP_XFRM_OFF, XL_NS_DRAW, "off", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (SP_XFRM, SP_XFRM_EXT, XL_NS_DRAW, "ext", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (SHAPE_PR, SP_PR_PRST_GEOM, XL_NS_DRAW, "prstGeom", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (SHAPE_PR, FILL_NONE,	XL_NS_DRAW, "noFill", GSF_XML_NO_CONTENT, &xlsx_chart_no_fill, NULL),
+    GSF_XML_IN_NODE (SHAPE_PR, FILL_SOLID,	XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, &xlsx_chart_solid_fill, NULL),
+      GSF_XML_IN_NODE (FILL_SOLID, COLOR_THEMED, XL_NS_DRAW, "schemeClr", GSF_XML_NO_CONTENT, &xlsx_draw_color_themed, &xlsx_draw_color_end),
+        GSF_XML_IN_NODE (COLOR_THEMED, COLOR_LUM, XL_NS_DRAW, "lumMod", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (FILL_SOLID, COLOR_RGB,	 XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, &xlsx_draw_color_rgb, &xlsx_draw_color_end),
+        GSF_XML_IN_NODE (COLOR_RGB, RGB_ALPHA,	   XL_NS_DRAW, "alpha", GSF_XML_NO_CONTENT, &xlsx_draw_color_alpha, NULL),
+        GSF_XML_IN_NODE (COLOR_RGB, RGB_GAMMA,	   XL_NS_DRAW, "gamma", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (COLOR_RGB, RGB_INV_GAMMA, XL_NS_DRAW, "invGamma", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (COLOR_RGB, RGB_SHADE,	   XL_NS_DRAW, "shade", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (COLOR_RGB, RGB_TINT,	   XL_NS_DRAW, "tint", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (COLOR_RGB, LN_DASH,	   XL_NS_DRAW, "prstDash", GSF_XML_NO_CONTENT, &xlsx_draw_line_dash, NULL),
+
+    GSF_XML_IN_NODE (SHAPE_PR, FILL_BLIP,	XL_NS_DRAW, "blipFill", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_BLIP,	XL_NS_DRAW, "blip", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_SRC,	XL_NS_DRAW, "srcRect", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_TILE,	XL_NS_DRAW, "tile", GSF_XML_NO_CONTENT, NULL, NULL),
+
+    GSF_XML_IN_NODE (SHAPE_PR, FILL_GRAD,	XL_NS_DRAW, "gradFill", GSF_XML_NO_CONTENT, &xlsx_chart_grad_fill, NULL),
+      GSF_XML_IN_NODE (FILL_GRAD, GRAD_LIST,	XL_NS_DRAW, "gsLst", GSF_XML_NO_CONTENT, NULL, NULL),
+       GSF_XML_IN_NODE (GRAD_LIST, GRAD_LIST_ITEM, XL_NS_DRAW, "gs", GSF_XML_NO_CONTENT, NULL, NULL),
+         GSF_XML_IN_NODE (GRAD_LIST_ITEM, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+      GSF_XML_IN_NODE (FILL_GRAD, GRAD_LINE,	XL_NS_DRAW, "lin", GSF_XML_NO_CONTENT, &xlsx_chart_grad_linear, NULL),
+
+    GSF_XML_IN_NODE (SHAPE_PR, FILL_PATT,	XL_NS_DRAW, "pattFill", GSF_XML_NO_CONTENT, &xlsx_chart_solid_fill, NULL),
+      GSF_XML_IN_NODE (FILL_PATT, FILL_PATT_BG,	XL_NS_DRAW, "bgClr", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (FILL_PATT_BG, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+      GSF_XML_IN_NODE (FILL_PATT, FILL_PATT_FG,	XL_NS_DRAW, "fgClr", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (FILL_PATT_FG, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+
+    GSF_XML_IN_NODE (SHAPE_PR, SHAPE_PR_LN, XL_NS_DRAW, "ln", GSF_XML_NO_CONTENT, &xlsx_style_line_start, &xlsx_style_line_end),
+      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_NOFILL, XL_NS_DRAW, "noFill", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_DASH, XL_NS_DRAW, "prstDash", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+      GSF_XML_IN_NODE (SHAPE_PR_LN, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+      GSF_XML_IN_NODE (SHAPE_PR_LN, FILL_PATT,	XL_NS_DRAW, "pattFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_MITER,	XL_NS_DRAW, "miter", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_ROUND,	XL_NS_DRAW, "round", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_HEAD,	XL_NS_DRAW, "headEnd", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_TAIL,	XL_NS_DRAW, "tailEnd", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (SHAPE_PR, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_BODY,	XL_NS_DRAW, "bodyPr", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_STYLE,	XL_NS_DRAW, "lstStyle", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_P,	XL_NS_DRAW, "p", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (TEXT_PR_P, PR_P_PR,	XL_NS_DRAW, "pPr", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (PR_P_PR, PR_P_PR_DEF, XL_NS_DRAW, "defRPr", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_CS, XL_NS_DRAW, "cs", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_EA, XL_NS_DRAW, "ea", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_LATIN, XL_NS_DRAW, "latin", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (PR_P_PR_DEF, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+            GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_UFILLTX, XL_NS_DRAW, "uFillTx", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_ULNTX, XL_NS_DRAW, "uLnTx", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (TEXT_PR_P, PR_P_PR_END,XL_NS_DRAW, "endParaRPr", GSF_XML_NO_CONTENT, NULL, NULL),
+
+  GSF_XML_IN_NODE (CHART_SPACE, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+
+  GSF_XML_IN_NODE (CHART_SPACE, CHART, XL_NS_CHART, "chart", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (CHART, PLOTAREA, XL_NS_CHART, "plotArea", GSF_XML_NO_CONTENT, &xlsx_plot_area, &xlsx_chart_pop),
+      GSF_XML_IN_NODE (PLOTAREA, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+      GSF_XML_IN_NODE_FULL (PLOTAREA, CAT_AXIS, XL_NS_CHART, "catAx", GSF_XML_NO_CONTENT, FALSE, TRUE,
+			    &xlsx_axis_start, &xlsx_axis_end, XLSX_AXIS_CAT),
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_AXID, XL_NS_CHART, "axId", GSF_XML_NO_CONTENT, &xlsx_axis_id, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_DELETE, XL_NS_CHART, "delete", GSF_XML_NO_CONTENT, &xlsx_axis_delete, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_NUMFMT, XL_NS_CHART, "numFmt", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_DELETE, XL_NS_CHART, "delete", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_MAJORTICKMARK, XL_NS_CHART, "majorTickMark", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_MINORTICKMARK, XL_NS_CHART, "minorTickMark", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE_FULL (CAT_AXIS, AXIS_MAJORTICK_UNIT, XL_NS_CHART, "majorUnit", GSF_XML_NO_CONTENT, FALSE, TRUE,
+			      &xlsx_axis_bound, NULL, GOG_AXIS_ELEM_MAJOR_TICK),
+        GSF_XML_IN_NODE_FULL (CAT_AXIS, AXIS_MINORTICK_UNIT, XL_NS_CHART, "minorUnit", GSF_XML_NO_CONTENT, FALSE, TRUE,
+			      &xlsx_axis_bound, NULL, GOG_AXIS_ELEM_MINOR_TICK),
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_TICK_LBL_SKIP, XL_NS_CHART, "tickLblSkip", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_TICK_MARK_SKIP, XL_NS_CHART, "tickMarkSkip", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_SCALING, XL_NS_CHART, "scaling", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE_FULL (AXIS_SCALING, AX_MIN, XL_NS_CHART, "min", GSF_XML_NO_CONTENT, FALSE, TRUE,
+				&xlsx_axis_bound, NULL, GOG_AXIS_ELEM_MIN),
+          GSF_XML_IN_NODE_FULL (AXIS_SCALING, AX_MAX, XL_NS_CHART, "max", GSF_XML_NO_CONTENT, FALSE, TRUE,
+				&xlsx_axis_bound, NULL, GOG_AXIS_ELEM_MAX),
+          GSF_XML_IN_NODE (AXIS_SCALING, AX_LOG, XL_NS_CHART, "logBase", GSF_XML_NO_CONTENT, &xlsx_chart_logbase, NULL),
+          GSF_XML_IN_NODE (AXIS_SCALING, AX_ORIENTATION, XL_NS_CHART, "orientation", GSF_XML_NO_CONTENT, &xlsx_axis_orientation, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, MAJOR_GRID, XL_NS_CHART, "majorGridlines", GSF_XML_NO_CONTENT,
+			 &xlsx_chart_gridlines, &xlsx_chart_pop),
+          GSF_XML_IN_NODE (MAJOR_GRID, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_POS, XL_NS_CHART, "axPos", GSF_XML_NO_CONTENT, &xlsx_axis_pos, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_TICKLBLPOS, XL_NS_CHART, "tickLblPos", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_AUTO, XL_NS_CHART, "auto", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_CROSSAX, XL_NS_CHART, "crossAx", GSF_XML_NO_CONTENT, &xlsx_axis_crossax, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_CROSSES, XL_NS_CHART, "crosses", GSF_XML_NO_CONTENT, &xlsx_axis_crosses, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, AXIS_CROSSES_AT, XL_NS_CHART, "crossesAt", GSF_XML_NO_CONTENT, &xlsx_axis_crosses_at, NULL),
+
+        GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_LBLALGN, XL_NS_CHART, "lblAlgn", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_LBLOFFSET, XL_NS_CHART, "lblOffset", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (CAT_AXIS, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (CAT_AXIS, TITLE, XL_NS_CHART, "title", GSF_XML_NO_CONTENT, NULL, NULL),		/* ID is used */
+          GSF_XML_IN_NODE (TITLE, LAYOUT, XL_NS_CHART, "layout", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (LAYOUT, LAST_LAYOUT,	    XL_NS_CHART, "lastLayout", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (LAYOUT, LAST_LAYOUT_OUTER, XL_NS_CHART, "lastLayoutOuter", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (LAYOUT, MAN_LAYOUT, XL_NS_CHART, "manualLayout", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_TARGET, XL_NS_CHART, "layoutTarget", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_XMODE, XL_NS_CHART, "xMode", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_YMODE, XL_NS_CHART, "yMode", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (TITLE, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+          GSF_XML_IN_NODE (TITLE, TEXT, XL_NS_CHART, "tx", GSF_XML_NO_CONTENT, &xlsx_chart_text_start, &xlsx_chart_text),
+            GSF_XML_IN_NODE (TEXT, TX_RICH, XL_NS_CHART, "rich", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (TX_RICH, TX_RICH_BODY, XL_NS_CHART, "bodyP", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (TX_RICH, TX_RICH_BODY_PR, XL_NS_DRAW, "bodyPr", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (TX_RICH, TX_RICH_STYLES, XL_NS_DRAW, "lstStyle", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (TX_RICH, TX_RICH_P, XL_NS_DRAW, "p", GSF_XML_NO_CONTENT, &xlsx_chart_p_start, NULL),
+                GSF_XML_IN_NODE (TX_RICH_P, PR_P_PR, XL_NS_DRAW, "pPr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+                GSF_XML_IN_NODE (TX_RICH_P, TX_RICH_R, XL_NS_DRAW, "r", GSF_XML_NO_CONTENT, NULL, NULL),
+                  GSF_XML_IN_NODE (TX_RICH_R, TX_RICH_R_PR, XL_NS_DRAW, "rPr", GSF_XML_NO_CONTENT, NULL, NULL),
+		    GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_CS, XL_NS_DRAW, "cs", GSF_XML_NO_CONTENT, NULL, NULL),
+		    GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_EA, XL_NS_DRAW, "ea", GSF_XML_NO_CONTENT, NULL, NULL),
+		    GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_LATIN, XL_NS_DRAW, "latin", GSF_XML_NO_CONTENT, NULL, NULL),
+		    GSF_XML_IN_NODE (TX_RICH_R_PR, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+		    GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_UFILLTX, XL_NS_DRAW, "uFillTx", GSF_XML_NO_CONTENT, NULL, NULL),
+		    GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_ULNTX, XL_NS_DRAW, "uLnTx", GSF_XML_NO_CONTENT, NULL, NULL),
+                  GSF_XML_IN_NODE (TX_RICH_R, TX_RICH_R_T, XL_NS_DRAW,  "t", GSF_XML_CONTENT, NULL, &xlsx_chart_text_content),
+            GSF_XML_IN_NODE (TEXT, STR_REF, XL_NS_CHART, "strRef", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (STR_REF, FUNC,	XL_NS_CHART,	"f",	GSF_XML_CONTENT, NULL, &xlsx_chart_ser_f),
+              GSF_XML_IN_NODE (STR_REF, STR_CACHE, XL_NS_CHART,	"strCache", GSF_XML_NO_CONTENT, NULL, NULL),
+                GSF_XML_IN_NODE (STR_CACHE, STR_CACHE_COUNT, XL_NS_CHART,"ptCount", GSF_XML_NO_CONTENT, NULL, NULL),
+                GSF_XML_IN_NODE (STR_CACHE, STR_PT, XL_NS_CHART,"pt", GSF_XML_NO_CONTENT, NULL, NULL),
+                  GSF_XML_IN_NODE (STR_PT, STR_VAL, XL_NS_CHART,"v", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (TITLE, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+
+      GSF_XML_IN_NODE_FULL (PLOTAREA, VAL_AXIS, XL_NS_CHART, "valAx", GSF_XML_NO_CONTENT, FALSE, TRUE,
+			    &xlsx_axis_start, &xlsx_axis_end, XLSX_AXIS_VAL),
+	GSF_XML_IN_NODE (VAL_AXIS, AXIS_AXID, XL_NS_CHART, "axId", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (VAL_AXIS, AXIS_DELETE, XL_NS_CHART, "delete", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (VAL_AXIS, TITLE, XL_NS_CHART, "title", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (VAL_AXIS, AXIS_SCALING, XL_NS_CHART, "scaling", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+	GSF_XML_IN_NODE (VAL_AXIS, AXIS_POS, XL_NS_CHART, "axPos", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (VAL_AXIS, MAJOR_GRID, XL_NS_CHART, "majorGridlines", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+	GSF_XML_IN_NODE (VAL_AXIS, AXIS_NUMFMT, XL_NS_CHART, "numFmt", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+	GSF_XML_IN_NODE (VAL_AXIS, AXIS_MAJORTICKMARK, XL_NS_CHART, "majorTickMark", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+	GSF_XML_IN_NODE (VAL_AXIS, AXIS_MINORTICKMARK, XL_NS_CHART, "minorTickMark", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (VAL_AXIS, AXIS_MAJORTICK_UNIT, XL_NS_CHART, "majorUnit", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (VAL_AXIS, AXIS_MINORTICK_UNIT, XL_NS_CHART, "minorUnit", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (VAL_AXIS, VAL_AXIS_TICKLBLPOS, XL_NS_CHART, "tickLblPos", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+	GSF_XML_IN_NODE (VAL_AXIS, AXIS_CROSSAX, XL_NS_CHART, "crossAx", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (VAL_AXIS, AXIS_CROSSES, XL_NS_CHART, "crosses", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (VAL_AXIS, AXIS_CROSSES_AT, XL_NS_CHART, "crossesAt", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (VAL_AXIS, VAL_AXIS_CROSSBETWEEN, XL_NS_CHART, "crossBetween", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (VAL_AXIS, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (VAL_AXIS, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+	
+      GSF_XML_IN_NODE_FULL (PLOTAREA, DATE_AXIS, XL_NS_CHART, "dateAx", GSF_XML_NO_CONTENT, FALSE, TRUE,
+                            &xlsx_axis_start, &xlsx_axis_end, XLSX_AXIS_DATE),
+        GSF_XML_IN_NODE (DATE_AXIS, AXIS_AUTO, XL_NS_CHART, "auto", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (DATE_AXIS, AXIS_AXID, XL_NS_CHART, "axId", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (DATE_AXIS, AXIS_POS, XL_NS_CHART, "axPos", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (DATE_AXIS, AXIS_CROSSAX, XL_NS_CHART, "crossAx", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (DATE_AXIS, AXIS_CROSSES, XL_NS_CHART, "crosses", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (DATE_AXIS, AXIS_CROSSES_AT, XL_NS_CHART, "crossesAt", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (DATE_AXIS, AXIS_DELETE, XL_NS_CHART, "delete", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (DATE_AXIS, AXIS_SCALING, XL_NS_CHART, "scaling", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (DATE_AXIS, MAJOR_GRID, XL_NS_CHART, "majorGridlines", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+	GSF_XML_IN_NODE (DATE_AXIS, AXIS_NUMFMT, XL_NS_CHART, "numFmt", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (DATE_AXIS, AXIS_MAJORTICKMARK, XL_NS_CHART, "majorTickMark", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+        GSF_XML_IN_NODE (DATE_AXIS, VAL_AXIS_TICKLBLPOS, XL_NS_CHART, "tickLblPos", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+        GSF_XML_IN_NODE (DATE_AXIS, CAT_AXIS_LBLOFFSET, XL_NS_CHART, "lblOffset", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (DATE_AXIS, VAL_AXIS_TICKLBLPOS, XL_NS_CHART, "tickLblPos", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+	GSF_XML_IN_NODE (DATE_AXIS, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (DATE_AXIS, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+	
+      GSF_XML_IN_NODE (PLOTAREA, LAYOUT, XL_NS_CHART, "layout", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (LAYOUT, LAST_LAYOUT,	    XL_NS_CHART, "lastLayout", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (LAYOUT, LAST_LAYOUT_OUTER, XL_NS_CHART, "lastLayoutOuter", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (LAYOUT, MAN_LAYOUT, XL_NS_CHART, "manualLayout", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_XMODE, XL_NS_CHART, "xMode", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_YMODE, XL_NS_CHART, "yMode", GSF_XML_NO_CONTENT, NULL, NULL),
+
+      GSF_XML_IN_NODE (PLOTAREA, SCATTER, XL_NS_CHART,	"scatterChart", GSF_XML_NO_CONTENT, xlsx_chart_xy, &xlsx_plot_end),
+        GSF_XML_IN_NODE (SCATTER, SCATTER_STYLE, XL_NS_CHART,	"scatterStyle", GSF_XML_NO_CONTENT, &xlsx_scatter_style, NULL),
+        GSF_XML_IN_NODE (SCATTER, PLOT_AXIS_ID, XL_NS_CHART,           "axId", GSF_XML_NO_CONTENT, &xlsx_plot_axis_id, NULL),
+
+        GSF_XML_IN_NODE (SCATTER, SERIES, XL_NS_CHART,	"ser", GSF_XML_NO_CONTENT, &xlsx_chart_ser_start, &xlsx_chart_ser_end),
+          GSF_XML_IN_NODE (SERIES, SERIES_IDX, XL_NS_CHART,	"idx", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SERIES, SERIES_ORDER, XL_NS_CHART,	"order", GSF_XML_NO_CONTENT, NULL, NULL),
+
+          GSF_XML_IN_NODE_FULL (SERIES, SERIES_CAT, XL_NS_CHART,"cat", GSF_XML_NO_CONTENT, FALSE, TRUE,
+			   &xlsx_ser_type_start, &xlsx_ser_type_end, GOG_MS_DIM_CATEGORIES),
+            GSF_XML_IN_NODE (SERIES_CAT, STR_REF, XL_NS_CHART,	"strRef", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+            GSF_XML_IN_NODE (SERIES_CAT, NUM_LIT, XL_NS_CHART,  "numLit", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (NUM_LIT, NUM_LIT_FMT, XL_NS_CHART,   "formatCode", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (NUM_LIT, NUM_LIT_COUNT, XL_NS_CHART, "ptCount", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (NUM_LIT, NUM_LIT_PT, XL_NS_CHART,     "pt", GSF_XML_NO_CONTENT, NULL, NULL),
+                GSF_XML_IN_NODE (NUM_LIT_PT, NUM_LIT_PT_VAL, XL_NS_CHART,     "v", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (SERIES_CAT, NUM_REF, XL_NS_CHART,	"numRef", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (NUM_REF, FUNC, XL_NS_CHART,	"f", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+              GSF_XML_IN_NODE (NUM_REF, NUM_CACHE, XL_NS_CHART,	"numCache", GSF_XML_NO_CONTENT, NULL, NULL),
+                GSF_XML_IN_NODE (NUM_CACHE, NUM_CACHE_FMT, XL_NS_CHART,	 "formatCode", GSF_XML_NO_CONTENT, NULL, NULL),
+                GSF_XML_IN_NODE (NUM_CACHE, NUM_CACHE_COUNT, XL_NS_CHART,"ptCount", GSF_XML_NO_CONTENT, NULL, NULL),
+                GSF_XML_IN_NODE (NUM_CACHE, NUM_PT, XL_NS_CHART,"pt", GSF_XML_NO_CONTENT, NULL, NULL),
+                  GSF_XML_IN_NODE (NUM_PT, NUM_VAL, XL_NS_CHART,"v", GSF_XML_NO_CONTENT, NULL, NULL),
+
+          GSF_XML_IN_NODE_FULL (SERIES, SERIES_VAL, XL_NS_CHART,	"val", GSF_XML_NO_CONTENT, FALSE, TRUE,
+			   &xlsx_ser_type_start, &xlsx_ser_type_end, GOG_MS_DIM_VALUES),
+            GSF_XML_IN_NODE (SERIES_VAL, NUM_REF, XL_NS_CHART,	"numRef", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+
+          GSF_XML_IN_NODE_FULL (SERIES, SERIES_X_VAL, XL_NS_CHART,	"xVal", GSF_XML_NO_CONTENT, FALSE, TRUE,
+			   &xlsx_ser_type_start, &xlsx_ser_type_end, GOG_MS_DIM_CATEGORIES),
+            GSF_XML_IN_NODE (SERIES_X_VAL, NUM_REF, XL_NS_CHART,	"numRef", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+            GSF_XML_IN_NODE (SERIES_X_VAL, NUM_LIT, XL_NS_CHART,	"numLit", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+
+          GSF_XML_IN_NODE_FULL (SERIES, SERIES_Y_VAL, XL_NS_CHART,	"yVal", GSF_XML_NO_CONTENT, FALSE, TRUE,
+			   &xlsx_ser_type_start, &xlsx_ser_type_end, GOG_MS_DIM_VALUES),
+            GSF_XML_IN_NODE (SERIES_Y_VAL, NUM_REF, XL_NS_CHART,	"numRef", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+            GSF_XML_IN_NODE (SERIES_Y_VAL, NUM_LIT, XL_NS_CHART,	"numLit", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+
+          GSF_XML_IN_NODE_FULL (SERIES, SERIES_BUBBLES, XL_NS_CHART,	"bubbleSize", GSF_XML_NO_CONTENT, FALSE, TRUE,
+			   &xlsx_ser_type_start, &xlsx_ser_type_end, GOG_MS_DIM_BUBBLES),
+            GSF_XML_IN_NODE (SERIES_BUBBLES, NUM_REF, XL_NS_CHART,	"numRef", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+            GSF_XML_IN_NODE (SERIES_BUBBLES, NUM_LIT, XL_NS_CHART,	"numLit", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+
+          GSF_XML_IN_NODE (SERIES, TEXT, XL_NS_CHART,	"tx", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+
+          GSF_XML_IN_NODE (SERIES, SERIES_BUBBLES_3D, XL_NS_CHART,	"bubble3D", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SERIES, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+	GSF_XML_IN_NODE (SERIES, SERIES_SMOOTH, XL_NS_CHART, "smooth", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SERIES, SERIES_IDX, XL_NS_CHART,	"idx", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SERIES, SERIES_D_LBLS, XL_NS_CHART,	"dLbls", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (SERIES_D_LBLS, SERIES_D_LBL_POS, XL_NS_CHART,	"dLblPos", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (SERIES_D_LBLS, SERIES_D_LBL, XL_NS_CHART,	"dLbl", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (SERIES_D_LBL, SERIES_D_LBL_POS, XL_NS_CHART,	"dLblPos", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (SERIES_D_LBL, SERIES_D_LBL_IDX, XL_NS_CHART,	"idx", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (SERIES_D_LBL, SERIES_D_LBL_LAYOUT, XL_NS_CHART,	"layout", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (SERIES_D_LBL, SERIES_D_LBL_SHOW, XL_NS_CHART,	"showVal", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (SERIES_D_LBL, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+              GSF_XML_IN_NODE (SERIES_D_LBL, TEXT, XL_NS_CHART,	"tx", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (SERIES_D_LBL, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+	  GSF_XML_IN_NODE (SERIES_D_LBLS, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+	    GSF_XML_IN_NODE (SERIES_D_LBLS, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+	    GSF_XML_IN_NODE (SERIES_D_LBLS, SHOW_VAL, XL_NS_CHART, "showVal", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (SERIES_D_LBLS, NUM_FMT, XL_NS_CHART, "numFmt", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (SERIES_D_LBLS, SHOW_BUBBLE, XL_NS_CHART, "showBubbleSize", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (SERIES_D_LBLS, SHOW_CAT_NAME, XL_NS_CHART, "showCatName", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (SERIES_D_LBLS, SHOW_LEADERS, XL_NS_CHART, "showLeaderLines", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (SERIES_D_LBLS, SHOW_PERCENT, XL_NS_CHART, "showPercent", GSF_XML_NO_CONTENT, NULL, NULL),
+
+          GSF_XML_IN_NODE (SERIES, SERIES_PT, XL_NS_CHART,	"dPt", GSF_XML_NO_CONTENT, &xlsx_chart_pt_start, &xlsx_chart_pt_end),
+            GSF_XML_IN_NODE (SERIES_PT, PT_IDX, XL_NS_CHART,	"idx", GSF_XML_NO_CONTENT, &xlsx_chart_pt_index, NULL),
+            GSF_XML_IN_NODE (SERIES_PT, SHAPE_PR, XL_NS_CHART,	"spPr", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (SERIES_PT, PT_SEP, XL_NS_CHART,	"explosion", GSF_XML_NO_CONTENT, &xlsx_chart_pt_sep, NULL),
+            GSF_XML_IN_NODE (SERIES_PT, MARKER, XL_NS_CHART,	"marker", GSF_XML_NO_CONTENT, &xlsx_chart_marker_start, &xlsx_chart_marker_end),
+              GSF_XML_IN_NODE (MARKER, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+              GSF_XML_IN_NODE (MARKER, MARKER_SYMBOL, XL_NS_CHART, "symbol", GSF_XML_NO_CONTENT, &xlsx_chart_marker_symbol, NULL),
+              GSF_XML_IN_NODE (MARKER, MARKER_SIZE, XL_NS_CHART, "size", GSF_XML_NO_CONTENT, NULL, NULL),
+
+          GSF_XML_IN_NODE (SERIES, SERIES_ERR_BARS, XL_NS_CHART,"errBars", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SERIES_ERR_BARS_ERRBARTYPE, XL_NS_CHART, "errBarType",  GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SERIES_ERR_BARS_ERRDIR, XL_NS_CHART, "errDir", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SERIES_ERR_BARS_ERRVALTYPE, XL_NS_CHART, "errValType", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SERIES_ERR_BARS_MINUS, XL_NS_CHART, "minus", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (SERIES_ERR_BARS_MINUS, NUM_REF, XL_NS_CHART, "numRef", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+              GSF_XML_IN_NODE (SERIES_ERR_BARS_MINUS, NUM_LIT, XL_NS_CHART, "numLit", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SERIES_ERR_BARS_PLUS, XL_NS_CHART, "plus", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (SERIES_ERR_BARS_PLUS, NUM_REF, XL_NS_CHART, "numRef", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+              GSF_XML_IN_NODE (SERIES_ERR_BARS_PLUS, NUM_LIT, XL_NS_CHART, "numLit", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+
+      GSF_XML_IN_NODE (PLOTAREA, BUBBLE, XL_NS_CHART,	"bubbleChart", GSF_XML_NO_CONTENT, &xlsx_chart_bubble, &xlsx_plot_end),
+        GSF_XML_IN_NODE (BUBBLE, PLOT_AXIS_ID, XL_NS_CHART,	"axId", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (BUBBLE, SERIES, XL_NS_CHART,		"ser", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (BUBBLE, BUBBLE_SCALE, XL_NS_CHART,	"bubbleScale", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (BUBBLE, BUBBLE_NEGATIVES, XL_NS_CHART,	"showNegBubbles", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (BUBBLE, BUBBLE_SIZE_REP, XL_NS_CHART,	"sizeRepresents", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (BUBBLE, VARY_COLORS, XL_NS_CHART,	"varyColors", GSF_XML_NO_CONTENT, &xlsx_vary_colors, NULL),
+
+      GSF_XML_IN_NODE (PLOTAREA, BARCOL, XL_NS_CHART,	"barChart", GSF_XML_NO_CONTENT, &xlsx_chart_bar, &xlsx_plot_end),
+        GSF_XML_IN_NODE (BARCOL, PLOT_AXIS_ID,	XL_NS_CHART, "axId", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (BARCOL, SERIES,	XL_NS_CHART, "ser", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (BARCOL, BARCOL_DIR,	XL_NS_CHART, "barDir", GSF_XML_NO_CONTENT, &xlsx_chart_bar_dir, NULL),
+        GSF_XML_IN_NODE (BARCOL, BARCOL_OVERLAP, XL_NS_CHART,"overlap", GSF_XML_NO_CONTENT, &xlsx_chart_bar_overlap, NULL),
+        GSF_XML_IN_NODE (BARCOL, GROUPING,	XL_NS_CHART, "grouping", GSF_XML_NO_CONTENT, &xlsx_chart_bar_group, NULL),
+        GSF_XML_IN_NODE (BARCOL, GAP_WIDTH,	XL_NS_CHART, "gapWidth", GSF_XML_NO_CONTENT, &xlsx_chart_bar_gap, NULL),
+
+      GSF_XML_IN_NODE (PLOTAREA, LINE, XL_NS_CHART,	"lineChart", GSF_XML_NO_CONTENT, &xlsx_chart_line, &xlsx_plot_end),
+        GSF_XML_IN_NODE (LINE, PLOT_AXIS_ID, XL_NS_CHART,"axId", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+        GSF_XML_IN_NODE (LINE, SERIES, XL_NS_CHART,	"ser", GSF_XML_NO_CONTENT, NULL, NULL),					/* 2nd Def */
+          GSF_XML_IN_NODE (SERIES, MARKER, XL_NS_CHART,	"marker", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (MARKER, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+            GSF_XML_IN_NODE (MARKER, MARKER_SYMBOL, XL_NS_CHART, "symbol", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (MARKER, MARKER_SIZE, XL_NS_CHART, "size", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (LINE, PLOT_AXIS_ID, XL_NS_CHART,"axId", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+        GSF_XML_IN_NODE (LINE, GROUPING, XL_NS_CHART,	"grouping", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+        GSF_XML_IN_NODE (LINE, MARKER, XL_NS_CHART,	"marker", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+
+      GSF_XML_IN_NODE (PLOTAREA, AREA, XL_NS_CHART,	"areaChart", GSF_XML_NO_CONTENT, &xlsx_chart_area, &xlsx_plot_end),
+        GSF_XML_IN_NODE (AREA, PLOT_AXIS_ID, XL_NS_CHART,"axId", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+        GSF_XML_IN_NODE (AREA, SERIES, XL_NS_CHART,	"ser", GSF_XML_NO_CONTENT, NULL, NULL),					/* 2nd Def */
+        GSF_XML_IN_NODE (AREA, GROUPING, XL_NS_CHART,	"grouping", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+
+      GSF_XML_IN_NODE (PLOTAREA, RADAR, XL_NS_CHART,	"radarChart", GSF_XML_NO_CONTENT, &xlsx_chart_radar, &xlsx_plot_end),
+        GSF_XML_IN_NODE (RADAR, PLOT_AXIS_ID, XL_NS_CHART,  "axId", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+        GSF_XML_IN_NODE (RADAR, SERIES, XL_NS_CHART,	  "ser", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+        GSF_XML_IN_NODE (RADAR, RADAR_STYLE, XL_NS_CHART, "radarStyle", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (RADAR, VARY_COLORS, XL_NS_CHART, "varyColors", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+
+      GSF_XML_IN_NODE (PLOTAREA, PIE, XL_NS_CHART,	"pieChart", GSF_XML_NO_CONTENT, &xlsx_chart_pie, &xlsx_plot_end),
+        GSF_XML_IN_NODE (PIE, SERIES, XL_NS_CHART,	"ser", GSF_XML_NO_CONTENT, NULL, NULL),					/* 2nd Def */
+          GSF_XML_IN_NODE (SERIES, PIE_SER_SEP, XL_NS_CHART,	"explosion", GSF_XML_NO_CONTENT, &xlsx_chart_pie_sep, NULL),
+        GSF_XML_IN_NODE (PIE, VARY_COLORS, XL_NS_CHART,	"varyColors", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+        GSF_XML_IN_NODE (PIE, PIE_FIRST_SLICE, XL_NS_CHART,	"firstSliceAng", GSF_XML_NO_CONTENT, NULL, NULL),
+
+      GSF_XML_IN_NODE (PLOTAREA, OF_PIE, XL_NS_CHART,	"ofPieChart", GSF_XML_NO_CONTENT, &xlsx_chart_pie, &xlsx_plot_end),
+        GSF_XML_IN_NODE (OF_PIE, OF_PIE_TYPE,	XL_NS_CHART, "ofPieType", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (OF_PIE, SERIES,	XL_NS_CHART, "ser", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
+        GSF_XML_IN_NODE (OF_PIE, SERIES_LINES,	XL_NS_CHART, "serLines", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SERIES_LINES, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (OF_PIE, PIE_GAP_WIDTH,	XL_NS_CHART, "gapWidth", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (OF_PIE, VARY_COLORS,	XL_NS_CHART, "varyColors", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (OF_PIE, OF_2ND_PIE,	XL_NS_CHART, "secondPieSize", GSF_XML_NO_CONTENT, NULL, NULL),
+
+      GSF_XML_IN_NODE (PLOTAREA, DOUGHNUT, XL_NS_CHART,	"doughnutChart", GSF_XML_NO_CONTENT, &xlsx_chart_ring, &xlsx_plot_end),
+        GSF_XML_IN_NODE (DOUGHNUT, SERIES, XL_NS_CHART,	"ser", GSF_XML_NO_CONTENT, NULL, NULL),					/* 2nd Def */
+        GSF_XML_IN_NODE (DOUGHNUT, VARY_COLORS, XL_NS_CHART,	"varyColors", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (DOUGHNUT, PIE_FIRST_SLICE, XL_NS_CHART,	"firstSliceAng", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+        GSF_XML_IN_NODE (DOUGHNUT, HOLE_SIZE, XL_NS_CHART,		"holeSize", GSF_XML_NO_CONTENT, NULL, NULL),
+
+      GSF_XML_IN_NODE (PLOTAREA, DATA_TABLE, XL_NS_CHART, "dTable", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (DATA_TABLE, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (DATA_TABLE, TEXT_PR, XL_NS_CHART,  "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+        GSF_XML_IN_NODE (DATA_TABLE, DT_SHOW_H_BORDER, XL_NS_CHART, "showHorzBorder", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (DATA_TABLE, DT_SHOW_V_BORDER, XL_NS_CHART, "showVertBorder", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (DATA_TABLE, DT_SHOW_KEYS, XL_NS_CHART, "showKeys", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (DATA_TABLE, DT_SHOW_OUTLINE, XL_NS_CHART, "showOutline", GSF_XML_NO_CONTENT, NULL, NULL),
+
+    GSF_XML_IN_NODE (CHART, TITLE, XL_NS_CHART, "title", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+
+    GSF_XML_IN_NODE (CHART, LEGEND, XL_NS_CHART, "legend", GSF_XML_NO_CONTENT, &xlsx_chart_legend, NULL),
+      GSF_XML_IN_NODE (LEGEND, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+      GSF_XML_IN_NODE (LEGEND, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+      GSF_XML_IN_NODE (LEGEND, LAYOUT, XL_NS_CHART, "layout", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+      GSF_XML_IN_NODE (LEGEND, LEGEND_POS, XL_NS_CHART, "legendPos", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (CHART, CHART_HIDDEN, XL_NS_CHART, "plotVisOnly", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (CHART, CHART_BLANKS, XL_NS_CHART, "dispBlanksAs", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (CHART, AUTO_TITLE_DEL, XL_NS_CHART, "autoTitleDeleted", GSF_XML_NO_CONTENT, NULL, NULL),
+
+  GSF_XML_IN_NODE (CHART_SPACE, STYLE, XL_NS_CHART, "style", GSF_XML_NO_CONTENT, NULL, NULL),
+  GSF_XML_IN_NODE (CHART_SPACE, PRINT_SETTINGS, XL_NS_CHART, "printSettings", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (PRINT_SETTINGS, PAGE_SETUP, XL_NS_CHART, "pageSetup", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (PRINT_SETTINGS, PAGE_MARGINS, XL_NS_CHART, "pageMargins", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (PRINT_SETTINGS, HEADER_FOOTER, XL_NS_CHART, "headerFooter", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (HEADER_FOOTER, ODD_HEADER, XL_NS_CHART, "oddHeader", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (HEADER_FOOTER, ODD_FOOTER, XL_NS_CHART, "oddFooter", GSF_XML_NO_CONTENT, NULL, NULL),
+  GSF_XML_IN_NODE (CHART_SPACE, LANG, XL_NS_CHART, "lang", GSF_XML_NO_CONTENT, NULL, NULL),
+  GSF_XML_IN_NODE (CHART_SPACE, USER_SHAPE, XL_NS_CHART, "userShapes", GSF_XML_NO_CONTENT, NULL, NULL),
+GSF_XML_IN_NODE_END
+};
+
+/***********************************************************************/
+
+static void
+cb_axis_set_position (GObject *axis, XLSXAxisInfo *info,
+		      XLSXReadState *state)
+{
+	if (info->deleted) {
+		GSList *l = gog_chart_get_axes (state->chart, gog_axis_get_atype (GOG_AXIS (axis))), *cur;
+		GogAxis *visible = NULL;
+
+		for (cur = l; cur; cur = cur->next) {
+			gboolean invisible;
+			g_object_get (cur->data, "invisible", &invisible, NULL);
+			if (!invisible) {
+				visible = GOG_AXIS (cur->data);
+				break;
+			}
+		}
+		if (visible) {
+			GSList *l1, *cur1;
+
+			l1 = g_slist_copy ((GSList *) gog_axis_contributors (GOG_AXIS (axis)));
+			for (cur1 = l1; cur1; cur1 = cur1->next) {
+				if (GOG_IS_PLOT (cur1->data))
+					gog_plot_set_axis (GOG_PLOT (cur1->data), visible);
+			}
+			g_slist_free (l1);
+			/* now reparent the children of the hidden axis */
+			l1 = gog_object_get_children (GOG_OBJECT (axis), NULL);
+			for (cur1 = l1; cur1; cur1 = cur1->next) {
+				GogObject *obj = GOG_OBJECT (cur1->data);
+				GogObjectRole const *role = obj->role;
+				gog_object_clear_parent (obj);
+				gog_object_set_parent (obj, GOG_OBJECT (visible), role, obj->id);
+			}
+			g_slist_free (l1);
+		}
+	} else if (info->cross_id) {
+		XLSXAxisInfo *cross_info = g_hash_table_lookup (state->axis.by_id, info->cross_id);
+		GogObject *obj;
+		g_return_if_fail (cross_info != NULL);
+		obj = GOG_OBJECT (cross_info->axis);
+		if (go_finite (cross_info->cross_value)) {
+			GnmValue *value = value_new_float (cross_info->cross_value);
+			GnmExprTop const *texpr = gnm_expr_top_new_constant (value);
+			gog_dataset_set_dim (GOG_DATASET (obj), GOG_AXIS_ELEM_CROSS_POINT,
+				gnm_go_data_scalar_new_expr (state->sheet, texpr), NULL);
+		}
+		g_object_set (obj, "pos", info->cross, "cross-axis-id", gog_object_get_id (GOG_OBJECT (axis)), NULL);
+	}
+}
+
+static void
+xlsx_axis_cleanup (XLSXReadState *state)
+{
+	GSList *list, *ptr;
+
+	/* clean out axis that were auto created */
+	list = gog_object_get_children (GOG_OBJECT (state->chart), NULL);
+	for (ptr = list; ptr != NULL ; ptr = ptr->next)
+		if (GOG_IS_AXIS (ptr->data) &&
+		    NULL == g_hash_table_lookup (state->axis.by_obj, ptr->data)) {
+			if (gog_object_is_deletable (GOG_OBJECT (ptr->data))) {
+				gog_object_clear_parent	(GOG_OBJECT (ptr->data));
+				g_object_unref (G_OBJECT (ptr->data));
+			}
+		}
+	g_slist_free (list);
+
+	g_hash_table_foreach (state->axis.by_obj,
+		(GHFunc)cb_axis_set_position, state);
+	g_hash_table_destroy (state->axis.by_obj);
+	g_hash_table_destroy (state->axis.by_id);
+	state->axis.by_obj = state->axis.by_id = NULL;
+}
+
+static void
+xlsx_read_chart (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	xmlChar const *part_id = NULL;
+
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (gsf_xml_in_namecmp (xin, attrs[0], XL_NS_DOC_REL, "id"))
+			part_id = attrs[1];
+	if (NULL != part_id) {
+		/* leave it in 'state' for the frame to insert */
+		state->so = sheet_object_graph_new (NULL);
+
+		state->graph	 = sheet_object_graph_get_gog (state->so);
+		state->cur_obj   = gog_object_add_by_name (GOG_OBJECT (state->graph), "Chart", NULL);
+		state->chart	 = GOG_CHART (state->cur_obj);
+		state->cur_style = NULL;
+		state->obj_stack = NULL;
+		state->dim_type  = GOG_MS_DIM_LABELS;
+		state->axis.by_id  = g_hash_table_new_full (g_str_hash, g_str_equal,
+			NULL, (GDestroyNotify) xlsx_axis_info_free);
+		state->axis.by_obj = g_hash_table_new (g_direct_hash, g_direct_equal);
+		xlsx_parse_rel_by_id (xin, part_id, xlsx_chart_dtd, xlsx_ns);
+
+		if (NULL != state->obj_stack) {
+			g_warning ("left over content on chart object stack");
+			g_slist_free (state->obj_stack);
+			state->obj_stack = NULL;
+		}
+
+		xlsx_axis_cleanup (state);
+		if (NULL != state->cur_style) {
+			g_warning ("left over style");
+			g_object_unref (state->cur_style);
+			state->cur_style = NULL;
+		}
+		state->cur_obj   = NULL;
+		state->chart = NULL;
+		state->graph = NULL;
+	}
+}
+
+/**************************************************************************/
+#define CELL	0
+#define OFFSET	1
+#define FROM	0
+#define TO	4
+#define COL	0
+#define ROW	2
+
+static void
+xlsx_draw_anchor_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+
+	g_return_if_fail (state->so == NULL);
+	
+	memset ((gpointer)state->drawing_pos, 0, sizeof (state->drawing_pos));
+	state->drawing_pos_flags = 0;
+}
+
+static void
+xlsx_drawing_twoCellAnchor_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+
+	if (NULL == state->so) {
+		xlsx_warning (xin,
+			_("Dropping missing object"));
+	} else {
+		if ((state->drawing_pos_flags & 0xFF) == 0xFF) {
+			SheetObjectAnchor anchor;
+			GnmRange r;
+
+			range_init (&r,
+				state->drawing_pos[COL | FROM],
+				state->drawing_pos[ROW | FROM],
+				state->drawing_pos[COL | TO],
+				state->drawing_pos[ROW | TO]);
+
+#warning implement absolute offsets
+				sheet_object_anchor_init (&anchor, &r, NULL, GOD_ANCHOR_DIR_DOWN_RIGHT);
+				sheet_object_set_anchor (state->so, &anchor);
+				sheet_object_set_sheet (state->so, state->sheet);
+		} else
+			xlsx_warning (xin,
+				_("Dropping object with incomplete anchor %2x"), state->drawing_pos_flags);
+
+		if (state->cur_style) {
+			g_object_set (state->so, "style", state->cur_style, NULL);
+			g_object_unref (state->cur_style);
+			state->cur_style = NULL;
+		}
+		g_object_unref (state->so);
+		state->so = NULL;
+	}
+}
+
+static void
+xlsx_drawing_oneCellAnchor_end (GsfXMLIn *xin, GsfXMLBlob *blob)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+
+	state->drawing_pos[COL | TO] = state->drawing_pos[COL | FROM] + 5;
+	state->drawing_pos[ROW | TO] = state->drawing_pos[ROW | FROM] + 5;
+	state->drawing_pos_flags |= ((1 << (COL | TO)) | (1 << (ROW | TO)));
+	xlsx_drawing_twoCellAnchor_end (xin, blob);
+}
+
+static void
+xlsx_drawing_ext (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (attr_int64 (xin, attrs, "cx", state->drawing_pos + (COL | TO | OFFSET)))
+			state->drawing_pos_flags |= (1 << (COL | TO | OFFSET));
+		else if (attr_int64 (xin, attrs, "cy", state->drawing_pos + (ROW | TO | OFFSET)))
+			state->drawing_pos_flags |= (1 << (ROW | TO | OFFSET));
+}
+
+static void
+xlsx_drawing_pos (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	gint64 val;
+	char  *end;
+
+	errno = 0;
+	val = g_ascii_strtoll (xin->content->str, &end, 10);
+	if (errno == ERANGE || end == xin->content->str || *end != '\0')
+		return;
+
+	state->drawing_pos[xin->node->user_data.v_int] = val;
+	state->drawing_pos_flags |= 1 << xin->node->user_data.v_int;
+#if 0
+	fprintf (stderr, "%s %s %s = %" G_GINT64_FORMAT "\n",
+		 (xin->node->user_data.v_int & TO) ? "To" : "From",
+		 (xin->node->user_data.v_int & ROW) ? "Row" : "Col",
+		 (xin->node->user_data.v_int & OFFSET) ? "Offset" : "",
+		 val);
+#endif
+}
+
+static void
+xlsx_drawing_preset_geom (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	if (NULL != state->so) /* FIXME FIXME FIXME: how does this happen? */
+		return;
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (!strcmp (attrs[0], "prst")) {
+			/* TODO, use a hash here for all preset geometries */
+			if (!strcmp (attrs[1], "rect"))
+				state->so = g_object_new (GNM_SO_FILLED_TYPE, "is_oval", FALSE, NULL);
+			else if (!strcmp (attrs[1], "line"))
+				state->so = g_object_new (GNM_SO_LINE_TYPE, NULL);
+		}
+	if (state->so) {
+		GOStyle *style;
+		if (g_object_class_find_property (G_OBJECT_GET_CLASS (state->so), "style"))
+			g_object_get (state->so, "style", &style, NULL);
+		if (style) {
+			state->cur_style = go_style_dup (style);
+			g_object_unref (style);
+		}
+	}
+}
+
+static void
+xlsx_drawing_picture (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	state->so = g_object_new (SHEET_OBJECT_IMAGE_TYPE, NULL);
+}
+
+static void
+xlsx_blip_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
+	g_return_if_fail (IS_SHEET_OBJECT_IMAGE (state->so));
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (!strcmp (attrs[0], "r:embed")) {
+			GsfOpenPkgRel const *rel = gsf_open_pkg_lookup_rel_by_id (
+				gsf_xml_in_get_input (xin), attrs[1]);
+			GsfInput *input = gsf_open_pkg_open_rel (
+			        gsf_xml_in_get_input (xin), rel, NULL);
+			size_t size = gsf_input_size (input);
+			guint8 *data = g_new (guint8, size);
+			gsf_input_read (input, size, data);
+			sheet_object_image_set_image (SHEET_OBJECT_IMAGE (state->so),
+				gsf_open_pkg_rel_get_type (rel), data, size, FALSE);
+	}
+	
+}
+
+static GsfXMLInNode const xlsx_drawing_dtd[] = {
+GSF_XML_IN_NODE_FULL (START, START, -1, NULL, GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
+GSF_XML_IN_NODE_FULL (START, DRAWING, XL_NS_SS_DRAW, "wsDr", GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
+
+  GSF_XML_IN_NODE (DRAWING, TWO_CELL, XL_NS_SS_DRAW, "twoCellAnchor", GSF_XML_NO_CONTENT,
+		   &xlsx_draw_anchor_start, &xlsx_drawing_twoCellAnchor_end),
+    GSF_XML_IN_NODE (TWO_CELL, ANCHOR_FROM, XL_NS_SS_DRAW, "from", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE_FULL (ANCHOR_FROM, ANCHOR_FROM_COL,	XL_NS_SS_DRAW, "col",	 GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, FROM | COL | CELL),
+      GSF_XML_IN_NODE_FULL (ANCHOR_FROM, ANCHOR_FROM_COL_OFF,	XL_NS_SS_DRAW, "colOff", GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, FROM | COL | OFFSET),
+      GSF_XML_IN_NODE_FULL (ANCHOR_FROM, ANCHOR_FROM_ROW,	XL_NS_SS_DRAW, "row",    GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, FROM | ROW | CELL),
+      GSF_XML_IN_NODE_FULL (ANCHOR_FROM, ANCHOR_FROM_ROW_OFF,	XL_NS_SS_DRAW, "rowOff", GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, FROM | ROW | OFFSET),
+    GSF_XML_IN_NODE (TWO_CELL, TWO_CELL_TO, XL_NS_SS_DRAW, "to", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE_FULL (TWO_CELL_TO, TWO_CELL_TO_COL,	XL_NS_SS_DRAW, "col",    GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, TO | COL | CELL),
+      GSF_XML_IN_NODE_FULL (TWO_CELL_TO, TWO_CELL_TO_COL_OFF,	XL_NS_SS_DRAW, "colOff", GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, TO | COL | OFFSET),
+      GSF_XML_IN_NODE_FULL (TWO_CELL_TO, TWO_CELL_TO_ROW,	XL_NS_SS_DRAW, "row",	 GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, TO | ROW | CELL),
+      GSF_XML_IN_NODE_FULL (TWO_CELL_TO, TWO_CELL_TO_ROW_OFF,	XL_NS_SS_DRAW, "rowOff", GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, TO | ROW | OFFSET),
+#undef FROM
+#undef TO
+#undef COL
+#undef ROW
+#undef CELL
+#undef OFFSET
+    GSF_XML_IN_NODE (TWO_CELL, SHAPE, XL_NS_SS_DRAW, "sp", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (SHAPE, SP_XFRM_STYLE, XL_NS_SS_DRAW, "style", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SP_XFRM_STYLE, LN_REF, XL_NS_DRAW, "lnRef", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (LN_REF, SCHEME_CLR, XL_NS_DRAW, "schemeClr", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (LN_REF, SCRGB_CLR, XL_NS_DRAW, "scrgbClr", GSF_XML_NO_CONTENT, xlsx_draw_color_rgb, xlsx_draw_color_end),
+          GSF_XML_IN_NODE (SP_XFRM_STYLE, FILL_REF, XL_NS_DRAW, "fillRef", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (FILL_REF, SCHEME_CLR, XL_NS_DRAW, "schemeClr", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (FILL_REF, SCRGB_CLR, XL_NS_DRAW, "scrgbClr", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SP_XFRM_STYLE, EFFECT_REF, XL_NS_DRAW, "effectRef", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (EFFECT_REF, SCHEME_CLR, XL_NS_DRAW, "schemeClr", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (EFFECT_REF, SCRGB_CLR, XL_NS_DRAW, "scrgbClr", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SP_XFRM_STYLE, FONT_REF, XL_NS_DRAW, "fontRef", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (FONT_REF, SCHEME_CLR, XL_NS_DRAW, "schemeClr", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (SHAPE, SHAPE_PR, XL_NS_SS_DRAW, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (SHAPE_PR, SP_PR_PRST_GEOM, XL_NS_DRAW, "prstGeom", GSF_XML_NO_CONTENT, &xlsx_drawing_preset_geom, NULL),
+        GSF_XML_IN_NODE (SHAPE_PR, SP_PR_XFRM, XL_NS_DRAW, "xfrm", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SP_PR_XFRM, SP_XFRM_STYLE, XL_NS_SS_DRAW, "style", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SP_PR_XFRM, SP_XFRM_OFF, XL_NS_DRAW, "off", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (SP_XFRM_OFF, SP_PR_PRST_GEOM, XL_NS_DRAW, "prstGeom", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (SP_XFRM_OFF, SHAPE_PR_LN, XL_NS_DRAW, "ln", GSF_XML_NO_CONTENT, xlsx_style_line_start, &xlsx_style_line_end),
+	      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_NOFILL, XL_NS_DRAW, "noFill", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_DASH, XL_NS_DRAW, "prstDash", GSF_XML_NO_CONTENT, &xlsx_draw_line_dash, NULL),		/* 2nd Def */
+	      GSF_XML_IN_NODE (SHAPE_PR_LN, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+	      GSF_XML_IN_NODE (SHAPE_PR_LN, FILL_PATT,	XL_NS_DRAW, "pattFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+	      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_MITER,	XL_NS_DRAW, "miter", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_ROUND,	XL_NS_DRAW, "round", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_HEAD,	XL_NS_DRAW, "headEnd", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_TAIL,	XL_NS_DRAW, "tailEnd", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SP_PR_XFRM, CHILD_OFF, XL_NS_DRAW, "chOff", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SP_PR_XFRM, CHILD_EXT, XL_NS_DRAW, "chExt", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (SHAPE_PR, SP_FILL_NONE,	XL_NS_DRAW, "noFill", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (SHAPE_PR, SP_FILL_SOLID,	XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),
+	  GSF_XML_IN_NODE (FILL_SOLID, COLOR_THEMED, XL_NS_DRAW, "schemeClr", GSF_XML_NO_CONTENT, &xlsx_draw_color_themed, &xlsx_draw_color_end),
+	    GSF_XML_IN_NODE (COLOR_THEMED, COLOR_LUM, XL_NS_DRAW, "lumMod", GSF_XML_NO_CONTENT, NULL, NULL),
+	  GSF_XML_IN_NODE (FILL_SOLID, COLOR_RGB,	 XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, &xlsx_draw_color_rgb, &xlsx_draw_color_end),
+	    GSF_XML_IN_NODE (COLOR_RGB, RGB_ALPHA,	   XL_NS_DRAW, "alpha", GSF_XML_NO_CONTENT, &xlsx_draw_color_alpha, NULL),
+	    GSF_XML_IN_NODE (COLOR_RGB, RGB_GAMMA,	   XL_NS_DRAW, "gamma", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (COLOR_RGB, RGB_INV_GAMMA, XL_NS_DRAW, "invGamma", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (COLOR_RGB, RGB_SHADE,	   XL_NS_DRAW, "shade", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (COLOR_RGB, RGB_TINT,	   XL_NS_DRAW, "tint", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (COLOR_RGB, LN_DASH,	   XL_NS_DRAW, "prstDash", GSF_XML_NO_CONTENT, NULL, NULL),
+
+	GSF_XML_IN_NODE (SHAPE_PR, FILL_BLIP,	XL_NS_DRAW, "blipFill", GSF_XML_NO_CONTENT, NULL, NULL),
+	  GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_BLIP,	XL_NS_DRAW, "blip", GSF_XML_NO_CONTENT, NULL, NULL),
+	  GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_SRC,	XL_NS_DRAW, "srcRect", GSF_XML_NO_CONTENT, NULL, NULL),
+	  GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_TILE,	XL_NS_DRAW, "tile", GSF_XML_NO_CONTENT, NULL, NULL),
+
+	GSF_XML_IN_NODE (SHAPE_PR, FILL_GRAD,	XL_NS_DRAW, "gradFill", GSF_XML_NO_CONTENT, xlsx_chart_grad_fill, NULL),
+	  GSF_XML_IN_NODE (FILL_GRAD, GRAD_LIST,	XL_NS_DRAW, "gsLst", GSF_XML_NO_CONTENT, NULL, NULL),
+	   GSF_XML_IN_NODE (GRAD_LIST, GRAD_LIST_ITEM, XL_NS_DRAW, "gs", GSF_XML_NO_CONTENT, xlsx_chart_grad_stop, NULL),
+	     GSF_XML_IN_NODE (GRAD_LIST_ITEM, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+	  GSF_XML_IN_NODE (FILL_GRAD, GRAD_LINE,	XL_NS_DRAW, "lin", GSF_XML_NO_CONTENT, NULL, NULL),
+
+	GSF_XML_IN_NODE (SHAPE_PR, FILL_PATT,	XL_NS_DRAW, "pattFill", GSF_XML_NO_CONTENT, NULL, NULL),
+	  GSF_XML_IN_NODE (FILL_PATT, FILL_PATT_BG,	XL_NS_DRAW, "bgClr", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (FILL_PATT_BG, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+	  GSF_XML_IN_NODE (FILL_PATT, FILL_PATT_FG,	XL_NS_DRAW, "fgClr", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (FILL_PATT_FG, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+
+	GSF_XML_IN_NODE (SHAPE_PR, SHAPE_PR_LN, XL_NS_DRAW, "ln", GSF_XML_NO_CONTENT, NULL, NULL),
+
+	GSF_XML_IN_NODE (SHAPE_PR, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),
+	  GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_BODY,	XL_NS_DRAW, "bodyPr", GSF_XML_NO_CONTENT, NULL, NULL),
+	  GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_STYLE,	XL_NS_DRAW, "lstStyle", GSF_XML_NO_CONTENT, NULL, NULL),
+	  GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_P,	XL_NS_DRAW, "p", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+	    GSF_XML_IN_NODE (TEXT_PR_P, TX_RICH_R, XL_NS_DRAW, "r", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (TX_RICH_R, TX_RICH_R_PR, XL_NS_DRAW, "rPr", GSF_XML_NO_CONTENT, NULL, NULL),
+		GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_CS, XL_NS_DRAW, "cs", GSF_XML_NO_CONTENT, NULL, NULL),
+		GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_EA, XL_NS_DRAW, "ea", GSF_XML_NO_CONTENT, NULL, NULL),
+		GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_LATIN, XL_NS_DRAW, "latin", GSF_XML_NO_CONTENT, NULL, NULL),
+		GSF_XML_IN_NODE (TX_RICH_R_PR, TEXT_FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),
+		  GSF_XML_IN_NODE (TEXT_FILL_SOLID, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),
+		GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_UFILLTX, XL_NS_DRAW, "uFillTx", GSF_XML_NO_CONTENT, NULL, NULL),
+		GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_ULNTX, XL_NS_DRAW, "uLnTx", GSF_XML_NO_CONTENT, NULL, NULL),
+
+	      GSF_XML_IN_NODE (TX_RICH_R, TX_RICH_R_T, XL_NS_DRAW,  "t", GSF_XML_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (TEXT_PR_P, PR_P_PR,	XL_NS_DRAW, "pPr", GSF_XML_NO_CONTENT, NULL, NULL),
+	      GSF_XML_IN_NODE (PR_P_PR, PR_P_PR_DEF, XL_NS_DRAW, "defRPr", GSF_XML_NO_CONTENT, NULL, NULL),
+		GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_CS, XL_NS_DRAW, "cs", GSF_XML_NO_CONTENT, NULL, NULL),
+		GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_EA, XL_NS_DRAW, "ea", GSF_XML_NO_CONTENT, NULL, NULL),
+		GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_LATIN, XL_NS_DRAW, "latin", GSF_XML_NO_CONTENT, NULL, NULL),
+		GSF_XML_IN_NODE (PR_P_PR_DEF, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+		GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_UFILLTX, XL_NS_DRAW, "uFillTx", GSF_XML_NO_CONTENT, NULL, NULL),
+		GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_ULNTX, XL_NS_DRAW, "uLnTx", GSF_XML_NO_CONTENT, NULL, NULL),
+	    GSF_XML_IN_NODE (TEXT_PR_P, PR_P_PR_END,XL_NS_DRAW, "endParaRPr", GSF_XML_NO_CONTENT, NULL, NULL),
+
+        GSF_XML_IN_NODE (SHAPE_PR, CXN_SP, XL_NS_SS_DRAW, "cxnSp", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (CXN_SP, CXN_SP_PR, XL_NS_SS_DRAW, "nvCxnSpPr", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (CXN_SP_PR, C_NV_CXN_SP, XL_NS_SS_DRAW, "cNvCxnSpPr", GSF_XML_NO_CONTENT, NULL, NULL),
+            GSF_XML_IN_NODE (CXN_SP_PR, C_NV_PR, XL_NS_SS_DRAW, "cNvPr", GSF_XML_NO_CONTENT, NULL, NULL),
+              GSF_XML_IN_NODE (C_NV_PR, HLINK_CLICK, XL_NS_DRAW, "hlinkClick", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (CXN_SP, SHAPE_PR, XL_NS_SS_DRAW, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (CXN_SP, SP_XFRM_STYLE, XL_NS_SS_DRAW, "style", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (SHAPE_PR, SP_PR_PRST_GEOM, XL_NS_DRAW, "prstGeom", GSF_XML_NO_CONTENT, NULL, NULL),
+
+      GSF_XML_IN_NODE (SHAPE, TX_BODY, XL_NS_SS_DRAW, "txBody", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (TX_BODY, LST_STYLE, XL_NS_DRAW, "lstStyle", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (TX_BODY, TX_BODY_PR, XL_NS_DRAW, "bodyPr", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (TX_BODY, TEXT_PR_P,	XL_NS_DRAW, "p", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+
+      GSF_XML_IN_NODE (SHAPE, NV_SP_PR, XL_NS_SS_DRAW, "nvSpPr", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (NV_SP_PR, C_NV_SP_PR, XL_NS_SS_DRAW, "cNvSpPr", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (C_NV_SP_PR, SP_LOCKS, XL_NS_DRAW, "spLocks", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (NV_SP_PR, C_NV_PR, XL_NS_SS_DRAW, "cNvPr", GSF_XML_NO_CONTENT, NULL, NULL),
+
+	GSF_XML_IN_NODE (SP_PR_XFRM, SP_XFRM_EXT, XL_NS_DRAW, "ext", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (SP_XFRM_EXT, SP_PR_PRST_GEOM, XL_NS_DRAW, "prstGeom", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (SP_PR_PRST_GEOM, AV_LST, XL_NS_DRAW, "avLst", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (SHAPE_PR, FILL_NONE,	XL_NS_DRAW, "noFill", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (SHAPE_PR, FILL_SOLID,	XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (SHAPE_PR, FILL_BLIP,	XL_NS_DRAW, "blipFill", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (SHAPE_PR, FILL_GRAD,	XL_NS_DRAW, "gradFill", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (SHAPE_PR, FILL_PATT,	XL_NS_DRAW, "pattFill", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (SHAPE_PR, SHAPE_PR_LN, XL_NS_DRAW, "ln", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (SHAPE_PR, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (SHAPE, TX_BODY, XL_NS_SS_DRAW, "txBody", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (TX_BODY, LST_STYLE, XL_NS_DRAW, "lstStyle", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+        GSF_XML_IN_NODE (TX_BODY, TX_BODY_PR, XL_NS_DRAW, "bodyPr", GSF_XML_NO_CONTENT, NULL, NULL),
+	GSF_XML_IN_NODE (TX_BODY, TEXT_PR_P,	XL_NS_DRAW, "p", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
+
+      GSF_XML_IN_NODE (SHAPE, NV_SP_PR, XL_NS_SS_DRAW, "nvSpPr", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (NV_SP_PR, C_NV_SP_PR, XL_NS_SS_DRAW, "cNvSpPr", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (C_NV_SP_PR, SP_LOCKS, XL_NS_DRAW, "spLocks", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (C_NV_SP_PR, HLINK_CLICK, XL_NS_DRAW, "hlinkClick", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (NV_SP_PR, C_NV_PR, XL_NS_SS_DRAW, "cNvPr", GSF_XML_NO_CONTENT, NULL, NULL),
+
+    GSF_XML_IN_NODE (TWO_CELL, GRAPHIC_FRAME, XL_NS_SS_DRAW, "graphicFrame", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (GRAPHIC_FRAME, GRAPHIC_PR, XL_NS_SS_DRAW, "nvGraphicFramePr", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GRAPHIC_PR, CNVPR, XL_NS_SS_DRAW, "cNvPr", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GRAPHIC_PR, GRAPHIC_PR_CHILD, XL_NS_SS_DRAW, "cNvGraphicFramePr", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (GRAPHIC_PR_CHILD, GRAPHIC_LOCKS, XL_NS_DRAW, "graphicFrameLocks", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (GRAPHIC_FRAME, GRAPHIC, XL_NS_DRAW, "graphic", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE_FULL (GRAPHIC, GRAPHIC_DATA, XL_NS_DRAW, "graphicData",
+			      GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
+          GSF_XML_IN_NODE (GRAPHIC_DATA, CHART, XL_NS_CHART, "chart", GSF_XML_NO_CONTENT, &xlsx_read_chart, NULL),
+          GSF_XML_IN_NODE (GRAPHIC_DATA, GRAPHIC_PR_CHILD, XL_NS_SS_DRAW, "cNvGraphicFramePr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+      GSF_XML_IN_NODE (GRAPHIC_FRAME, TWO_CELL_XFRM, XL_NS_SS_DRAW, "xfrm", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (TWO_CELL_XFRM, XFRM_OFF, XL_NS_DRAW, "off", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (TWO_CELL_XFRM, XFRM_EXT, XL_NS_DRAW, "ext", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (TWO_CELL, CLIENT_DATA, XL_NS_SS_DRAW, "clientData", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (TWO_CELL, CONTENT_PART, XL_NS_SS_DRAW, "contentPart", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (TWO_CELL, CXN_SP, XL_NS_SS_DRAW, "cxnSp", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (TWO_CELL, PICTURE, XL_NS_SS_DRAW, "pic", GSF_XML_NO_CONTENT, &xlsx_drawing_picture, NULL),
+      GSF_XML_IN_NODE (PICTURE, PIC_FILL_BLIP, XL_NS_SS_DRAW, "blipFill", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (PIC_FILL_BLIP, BLIP, XL_NS_DRAW, "blip", GSF_XML_NO_CONTENT, &xlsx_blip_start, NULL),
+        GSF_XML_IN_NODE (PIC_FILL_BLIP, BLIP_STRETCH, XL_NS_DRAW, "stretch", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (BLIP_STRETCH, BLIP_FILL_RECT, XL_NS_DRAW, "fillRect", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (PICTURE, NV_PIC_PR, XL_NS_SS_DRAW, "nvPicPr", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (NV_PIC_PR, C_NV_PIC_PR, XL_NS_SS_DRAW, "cNvPicPr", GSF_XML_NO_CONTENT, NULL, NULL),
+          GSF_XML_IN_NODE (C_NV_PIC_PR, PIC_LOCKS, XL_NS_DRAW, "picLocks", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (NV_PIC_PR, C_NV_PR, XL_NS_SS_DRAW, "cNvPr", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (PICTURE, SHAPE_PR, XL_NS_SS_DRAW, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (PICTURE, SP_XFRM_STYLE, XL_NS_SS_DRAW, "style", GSF_XML_NO_CONTENT, NULL, NULL),
+    GSF_XML_IN_NODE (TWO_CELL, GROUP_SP, XL_NS_SS_DRAW, "grpSp", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (GROUP_SP, SHAPE, XL_NS_SS_DRAW, "sp", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (GROUP_SP, CXN_SP, XL_NS_SS_DRAW, "cxnSp", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (GROUP_SP, PICTURE, XL_NS_SS_DRAW, "pic", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (GROUP_SP, GROUP_SP_PR, XL_NS_SS_DRAW, "grpSpPr", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP_PR, PIC_FILL_BLIP, XL_NS_SS_DRAW, "blipFill", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP_PR, EFFECT_DAG, XL_NS_SS_DRAW, "effectDag", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP_PR, EFFECT_LST, XL_NS_SS_DRAW, "effectLst", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP_PR, EXT_LST, XL_NS_SS_DRAW, "extLst", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP_PR, FILL_GRAD, XL_NS_DRAW, "gradFill", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP_PR, FILL_GRP, XL_NS_DRAW, "grpFill", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP_PR, FILL_NONE, XL_NS_DRAW, "noFill", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP_PR, FILL_PATT, XL_NS_DRAW, "pattFill", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP_PR, SCENE3D, XL_NS_DRAW, "scene3d", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP_PR, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP_PR, SP_PR_XFRM, XL_NS_DRAW, "xfrm", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (GROUP_SP, GROUP_SP, XL_NS_SS_DRAW, "grpSp", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (GROUP_SP, NV_GRP_SP_PR, XL_NS_SS_DRAW, "nvGrpSpPr", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (NV_GRP_SP_PR, C_NV_GRP_SP_PR, XL_NS_SS_DRAW, "cNvGrpSpPr", GSF_XML_NO_CONTENT, NULL, NULL),
+        GSF_XML_IN_NODE (NV_GRP_SP_PR, C_NV_PR, XL_NS_SS_DRAW, "cNvPr", GSF_XML_NO_CONTENT, NULL, NULL),
+      GSF_XML_IN_NODE (GROUP_SP, GRAPHIC_FRAME, XL_NS_SS_DRAW, "graphicFrame", GSF_XML_NO_CONTENT, NULL, NULL),
+
+  GSF_XML_IN_NODE (DRAWING, ONE_CELL, XL_NS_SS_DRAW, "oneCellAnchor", GSF_XML_NO_CONTENT,
+		   &xlsx_draw_anchor_start, &xlsx_drawing_oneCellAnchor_end),
+    GSF_XML_IN_NODE (ONE_CELL, ANCHOR_FROM, XL_NS_SS_DRAW, "from", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
+    GSF_XML_IN_NODE (ONE_CELL, ONE_CELL_EXT, XL_NS_SS_DRAW, "ext", GSF_XML_NO_CONTENT, &xlsx_drawing_ext, NULL),
+    GSF_XML_IN_NODE (ONE_CELL, CLIENT_DATA, XL_NS_SS_DRAW, "clientData", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+    GSF_XML_IN_NODE (ONE_CELL, GRAPHIC_FRAME, XL_NS_SS_DRAW, "graphicFrame", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
+GSF_XML_IN_NODE_END
+};
diff --git a/plugins/excel/xlsx-read.c b/plugins/excel/xlsx-read.c
index 6ace999..5c27792 100644
--- a/plugins/excel/xlsx-read.c
+++ b/plugins/excel/xlsx-read.c
@@ -50,6 +50,9 @@
 #include "sheet-object-graph.h"
 #include "sheet-object-cell-comment.h"
 #include "gnm-sheet-slicer.h"
+#include "gnm-so-filled.h"
+#include "gnm-so-line.h"
+#include "sheet-object-image.h"
 
 #include <goffice/goffice.h>
 
@@ -184,7 +187,11 @@ typedef struct {
 	GogObject	 *series_pt;
 	gboolean	  series_pt_has_index;
 	GOStyle	 *cur_style;
-	GOColor		  gocolor;
+	GOColor		 *gocolor;
+	gboolean	 *auto_color;
+	void (*color_setter) (gpointer data, GOColor color);
+	GOColor		  color;
+	gpointer	  color_data;
 	GOMarker	 *marker;
 	GOMarkerShape	  marker_symbol;
 	GogObject	 *cur_obj;
@@ -942,1566 +949,8 @@ xlsx_parse_sqref (GsfXMLIn *xin, xmlChar const *refs)
 #include "xlsx-read-pivot.c"
 
 /***********************************************************************/
-/* TO DO MOVE INTO xlsx-read-chart.c */
 
-static void
-xlsx_chart_push_obj (XLSXReadState *state, GogObject *obj)
-{
-	state->obj_stack = g_slist_prepend (state->obj_stack, state->cur_obj);
-	state->cur_obj = obj;
-
-#if 0
-	g_print ("push %s\n", G_OBJECT_TYPE_NAME (obj));
-#endif
-}
-
-static void
-xlsx_chart_pop_obj (XLSXReadState *state)
-{
-	GSList *obj_stack = state->obj_stack;
-	g_return_if_fail (obj_stack != NULL);
-
-#if 0
-	g_print ("push %s\n", G_OBJECT_TYPE_NAME (state->cur_obj));
-#endif
-
-	state->cur_obj = obj_stack->data;
-	state->obj_stack = g_slist_remove (state->obj_stack, state->cur_obj);
-}
-
-static void
-xlsx_chart_add_plot (GsfXMLIn *xin, char const *type)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	if (NULL != (state->plot = (GogPlot*) gog_plot_new_by_name (type)))
-		/* Add _before_ setting styles so theme does not override */
-		gog_object_add_by_name (GOG_OBJECT (state->chart),
-			"Plot", GOG_OBJECT (state->plot));
-}
-
-/* shared with pie of pie, and bar of pie */
-static void
-xlsx_vary_colors (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	int vary;
-	if (simple_bool (xin, attrs, &vary))
-		g_object_set (G_OBJECT (state->plot),
-			"vary-style-by-element", vary, NULL);
-}
-
-static void
-xlsx_chart_pie_sep (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	int sep;
-	if (simple_int (xin, attrs, &sep))
-		g_object_set (G_OBJECT (state->plot),
-			"default-separation", (double)(CLAMP (sep, 0, 500))/ 100., NULL);
-}
-
-/* shared with pie of pie, and bar of pie */
-static void xlsx_chart_pie (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogPiePlot"); }
-static void xlsx_chart_ring (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogRingPlot"); }
-
-/***********************************************************************/
-
-static void
-xlsx_chart_bar_dir (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	static EnumVal const dirs[] = {
-		{ "bar",	 TRUE },
-		{ "col",	 FALSE },
-		{ NULL, 0 }
-	};
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	int dir;
-
-	g_return_if_fail (state->plot != NULL);
-
-	if (simple_enum (xin, attrs, dirs, &dir))
-		g_object_set (G_OBJECT (state->plot), "horizontal", dir, NULL);
-}
-
-static void
-xlsx_chart_bar_overlap (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	int overlap;
-	g_return_if_fail (state->plot != NULL);
-	if (simple_int (xin, attrs, &overlap))
-		g_object_set (G_OBJECT (state->plot),
-			"overlap-percentage", CLAMP (overlap, -100, 100), NULL);
-}
-static void
-xlsx_chart_bar_group (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	char const *type = "normal";
-
-	g_return_if_fail (state->plot != NULL);
-
-	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
-		if (0 == strcmp (attrs[0], "val")) {
-			if (0 == strcmp (attrs[1], "percentStacked"))
-				type = "as_percentage";
-			else if (0 == strcmp (attrs[1], "stacked"))
-				type = "stacked";
-			g_object_set (G_OBJECT (state->plot), "type", type, NULL);
-		}
-}
-static void
-xlsx_chart_bar_gap (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	int gap;
-	if (simple_int (xin, attrs, &gap))
-		g_object_set (G_OBJECT (state->plot),
-			"gap-percentage", CLAMP (gap, 0, 500), NULL);
-}
-
-static void
-xlsx_chart_bar (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	xlsx_chart_add_plot (xin, "GogBarColPlot");
-}
-
-/***********************************************************************/
-
-static void
-xlsx_axis_info_free (XLSXAxisInfo *info)
-{
-	g_free (info->id);
-	g_free (info->cross_id);
-	if (NULL != info->axis)
-		g_object_unref (info->axis);
-	g_free (info);
-}
-
-static void
-xlsx_plot_axis_id (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	if (NULL == state->plot)
-		return;
-
-	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
-		if (0 == strcmp (attrs[0], "val")) {
-			XLSXAxisInfo *res = g_hash_table_lookup (state->axis.by_id, attrs[1]);
-			if (NULL == res) {
-				res = g_new0 (XLSXAxisInfo, 1);
-				res->id = g_strdup (attrs[1]);
-				res->axis	= NULL;
-				res->plots	= NULL;
-				res->type	= XLSX_AXIS_UNKNOWN;
-				res->compass	= GOG_POSITION_AUTO;
-				res->cross	= GOG_AXIS_CROSS;
-				res->cross_value = go_nan;
-				g_hash_table_replace (state->axis.by_id, res->id, res);
-#ifdef DEBUG_AXIS
-				g_print ("create %s = %p\n", attrs[1], res);
-#endif
-			}
-#ifdef DEBUG_AXIS
-			g_print ("add plot %p to %p\n", state->plot, res);
-#endif
-			res->plots = g_slist_prepend (res->plots, state->plot);
-		}
-}
-
-static void
-xlsx_axis_start (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	state->axis.obj	 = g_object_new (GOG_TYPE_AXIS, NULL);
-	state->axis.type = xin->node->user_data.v_int;
-	state->axis.info = NULL;
-	xlsx_chart_push_obj (state, GOG_OBJECT (state->axis.obj));
-}
-
-static void
-xlsx_axis_crosses_at (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	/* This element specifies where on the axis the perpendicular axis crosses. 
-	   The units are dependent on the type of axis.
-	   When specified as a child element of valAx, the value is a decimal number on the value axis. When specified as a
-	   child element of dateAx, the date is defined as a integer number of days relative to the base date of the current
-	   date base. When specified as a child element of catAx, the value is an integer category number, starting with 1
-	   as the first category.
-	*/
- 	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-
-	simple_float (xin, attrs, &state->axis.info->cross_value);
-}
-
-static void
-xlsx_axis_id (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
-		if (0 == strcmp (attrs[0], "val")) {
-			state->axis.info = g_hash_table_lookup (state->axis.by_id, attrs[1]);
-			if (NULL != state->axis.info) {
-				g_return_if_fail (state->axis.info->axis == NULL);
-				state->axis.info->axis = state->axis.obj;
-				g_hash_table_replace (state->axis.by_obj,
-					state->axis.obj, state->axis.info);
-			}
-#ifdef DEBUG_AXIS
-			g_print ("define %s = %p\n", attrs[1], state->axis.info);
-#endif
-		}
-}
-
-static void
-xlsx_axis_delete (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	int del = 0;
-	if (state->axis.info && simple_bool (xin, attrs, &del))
-		state->axis.info->deleted = del;
-	if (state->axis.info && del)
-		g_object_set (state->axis.info->axis, "invisible", TRUE, NULL);
-}
-static void
-xlsx_axis_orientation (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	static EnumVal const orients[] = {
-		{ "minMax",	 FALSE },
-		{ "maxMin",	 TRUE },
-		{ NULL, 0 }
-	};
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	int orient;
-	if (state->axis.info && simple_enum (xin, attrs, orients, &orient))
-		g_object_set (G_OBJECT (state->axis.obj),
-			"invert-axis", orient, NULL);
-}
-static void
-xlsx_chart_logbase (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	int base;
-	if (state->axis.info && simple_int (xin, attrs, &base))
-		g_object_set (G_OBJECT (state->axis.obj),
-			"map-name", "Log", NULL);
-}
-static void
-xlsx_axis_pos (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	static EnumVal const positions[] = {
-		{ "t",	 GOG_POSITION_N },
-		{ "b",	 GOG_POSITION_S },
-		{ "l",	 GOG_POSITION_W },
-		{ "r",	 GOG_POSITION_E },
-		{ NULL, 0 }
-	};
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	int position;
-#ifdef DEBUG_AXIS
-	g_print ("SET POS %s for %p\n", attrs[1],  state->axis.info);
-#endif
-	if (state->axis.info && simple_enum (xin, attrs, positions, &position))
-		state->axis.info->compass = position;
-}
-
-static void
-xlsx_axis_bound (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	gnm_float val;
-	if (state->axis.info && simple_float (xin, attrs, &val))
-		gog_dataset_set_dim (GOG_DATASET (state->axis.obj),
-			xin->node->user_data.v_int,
-			go_data_scalar_val_new (val), NULL);
-}
-
-static void
-xlsx_axis_crosses (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	static EnumVal const crosses[] = {
-		{ "autoZero",	GOG_AXIS_CROSS },
-		{ "max",	GOG_AXIS_AT_HIGH },
-		{ "min",	GOG_AXIS_AT_LOW },
-		{ NULL, 0 }
-	};
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	int cross;
-
-	if (state->axis.info && simple_enum (xin, attrs, crosses, &cross))
-		state->axis.info->cross = cross;
-}
-
-static void
-xlsx_axis_crossax (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	if (state->axis.info && !strcmp ((char const*) attrs[0], "val"))
-		state->axis.info->cross_id = g_strdup (attrs[1]);
-}
-
-static void
-xlsx_chart_gridlines (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	if (NULL != state->axis.obj) {
-		GogObject *grid = gog_object_add_by_name (
-			GOG_OBJECT (state->axis.obj), "MajorGrid", NULL);
-		xlsx_chart_push_obj (state, grid);
-	}
-}
-
-static void
-xlsx_axis_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-
-	/* Try to guess what type of axis to use */
-	if (NULL != state->axis.info) {
-		GogPlot *plot = state->axis.info->plots->data; /* just use the first */
-		char const *type = G_OBJECT_TYPE_NAME (plot);
-		char const *role = NULL;
-		GSList *ptr;
-
-		if (0 == strcmp (type, "GogRadarPlot") ||
-		    0 == strcmp (type, "GogRadarAreaPlot")) {
-			role = (state->axis.type == XLSX_AXIS_CAT
-				|| state->axis.type == XLSX_AXIS_DATE) ? "Radial-Axis" : "Circular-Axis";
-		} else if (0 == strcmp (type, "GogBubblePlot") ||
-			   0 == strcmp (type, "GogXYPlot")) {
-			/* both are VAL, use the position to decide */
-			if (state->axis.info->compass  == GOG_POSITION_N ||
-			    state->axis.info->compass  == GOG_POSITION_S)
-				role = "X-Axis";
-			else
-				role = "Y-Axis";
-		} else if (0 == strcmp (type, "GogBarColPlot")) {
-			gboolean h;
-			/* swap for bar plots */
-			g_object_get (G_OBJECT (plot), "horizontal", &h, NULL);
-			if (h)
-				role = (state->axis.type == XLSX_AXIS_CAT
-				        || state->axis.type == XLSX_AXIS_DATE) ? "Y-Axis" : "X-Axis";
-		}
-
-		if (NULL == role)
-			role = (state->axis.type == XLSX_AXIS_CAT
-				|| state->axis.type == XLSX_AXIS_DATE) ? "X-Axis" : "Y-Axis";
-
-		/* absorb a ref, and set the id, and atype */
-		gog_object_add_by_name (GOG_OBJECT (state->chart),
-			role, GOG_OBJECT (state->axis.obj));
-		g_object_ref (G_OBJECT (state->axis.obj));
-		for (ptr = state->axis.info->plots; ptr != NULL ; ptr = ptr->next) {
-#ifdef DEBUG_AXIS
-			g_print ("connect plot %p to %p in role %s\n", ptr->data, state->axis.obj, role);
-#endif
-			gog_plot_set_axis (ptr->data, state->axis.obj);
-		}
-
-		state->axis.obj  = NULL;
-		state->axis.info = NULL;
-	}
-
-	xlsx_chart_pop_obj (state);
-	state->axis.info = NULL;
-}
-
-static void xlsx_chart_area (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogAreaPlot"); }
-static void xlsx_chart_line (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogLinePlot"); }
-
-static void
-xlsx_chart_xy (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	xlsx_chart_add_plot (xin, "GogXYPlot");
-	g_object_set (G_OBJECT (state->plot), "default-style-has-fill", FALSE, NULL);
-}
-
-static void
-xlsx_scatter_style (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	static EnumVal styles[] = {
-		{"line",	0},
-		{"lineMarker",  1},
-		{"marker",      2},
-		{"none",	3},
-		{"smooth",      4},
-		{"smoothMarker", 5}
-	};
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	int style;
-
-	if (simple_enum (xin, attrs, styles, &style))
-		switch (style) {
-		case 0:
-			g_object_set (G_OBJECT (state->plot),
-			              "default-style-has-markers", FALSE,
-			              NULL);
-			break;
-		case 2:
-			g_object_set (G_OBJECT (state->plot),
-			              "default-style-has-lines", FALSE,
-			              NULL);
-			break;
-		case 3:
-			g_object_set (G_OBJECT (state->plot),
-			              "default-style-has-markers", FALSE,
-			              "default-style-has-lines", FALSE,
-			              NULL);
-			break;
-		case 4:
-			g_object_set (G_OBJECT (state->plot),
-			              "use-splines", TRUE,
-			              "default-style-has-markers", FALSE, NULL);
-			break;
-		case 5:
-			g_object_set (G_OBJECT (state->plot),
-			              "use-splines", TRUE,
-			              NULL);
-			break;
-		}
-}
-
-static void xlsx_chart_bubble (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogBubblePlot"); }
-static void xlsx_chart_radar (GsfXMLIn *xin, xmlChar const **attrs) { xlsx_chart_add_plot (xin, "GogRadarPlot"); }
-#if 0
-	char const *type = "GogRadarPlot";
-	gboolean with_markers = FALSE;
-	/* Irritants.  They put the sub type into a child record ... */
-	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
-		if (0 == strcmp (attrs[0], "type")) {
-			if (0 == strcmp (attrs[1], "filled"))
-				type = "as_percentage";
-			else if (0 == strcmp (attrs[1], "marker"))
-				type = "stacked";
-			g_object_set (G_OBJECT (state->plot), "type", type, NULL);
-		}
-		if (0 == strcmp (xin, attrs, "cx", state->drawing_pos + (COL | TO | OFFSET)))
-			state->drawing_pos_flags |= (1 << (COL | TO | OFFSET));
-	g_object_set (G_OBJECT (state->plot), "default-style-has-markers", with_markers, NULL);
-#endif
-
-static void
-xlsx_plot_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	state->plot = NULL;
-}
-
-static void
-xlsx_chart_ser_start (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	if (NULL != state->plot) {
-		state->series = gog_plot_new_series (state->plot);
-		xlsx_chart_push_obj (state, GOG_OBJECT (state->series));
-	}
-}
-static void
-xlsx_chart_ser_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	if (NULL != state->series) {
-		xlsx_chart_pop_obj (state);
-		state->series = NULL;
-	}
-}
-
-#warning shared from ms-chart.c for now, move to GOffice with the enum
-extern void XL_gog_series_set_dim (GogSeries *series, GogMSDimType ms_type, GOData *val);
-static void
-xlsx_chart_ser_f (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	if (NULL != state->series) {
-		GnmParsePos pp;
-		GnmExprTop const *texpr = xlsx_parse_expr (xin, xin->content->str,
-			parse_pos_init_sheet (&pp, state->sheet));
-
-		XL_gog_series_set_dim (state->series, state->dim_type,
-			(state->dim_type != GOG_MS_DIM_LABELS)
-			? gnm_go_data_vector_new_expr (state->sheet, texpr)
-			: gnm_go_data_scalar_new_expr (state->sheet, texpr));
-	} else if (GOG_IS_LABEL (state->cur_obj)) {
-		GnmParsePos pp;
-		GnmExprTop const *texpr = xlsx_parse_expr (xin, xin->content->str,
-			parse_pos_init_sheet (&pp, state->sheet));
-
-		gog_dataset_set_dim (GOG_DATASET (state->cur_obj), 0,
-			gnm_go_data_scalar_new_expr (state->sheet, texpr), NULL);
-	}
-}
-
-static void
-xlsx_ser_type_start (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	state->dim_type = xin->node->user_data.v_int;
-}
-
-static void
-xlsx_ser_type_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	state->dim_type = GOG_MS_DIM_LABELS;
-}
-
-static void
-xlsx_chart_legend (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	gog_object_add_by_name (GOG_OBJECT (state->chart), "Legend", NULL);
-}
-
-static void
-xlsx_chart_pt_start (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	if (NULL != state->series) {
-		state->series_pt_has_index = FALSE;
-		state->series_pt = gog_object_add_by_name (
-			GOG_OBJECT (state->series), "Point", NULL);
-		xlsx_chart_push_obj (state, state->series_pt);
-	}
-}
-
-static void
-xlsx_chart_pt_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	if (NULL != state->series) {
-		xlsx_chart_pop_obj (state);
-		if (!state->series_pt_has_index) {
-			gog_object_clear_parent (state->series_pt);
-			g_object_unref (state->series_pt);
-		}
-		state->series_pt = NULL;
-	}
-}
-
-static void
-xlsx_chart_pt_index (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	int tmp;
-
-	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
-		if (attr_int (xin, attrs, "val", &tmp)) {
-			state->series_pt_has_index = TRUE;
-			g_object_set (state->series_pt, "index", tmp, NULL);
-		}
-}
-
-static void
-xlsx_chart_pt_sep (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	int sep;
-	if (simple_int (xin, attrs, &sep) &&
-	    g_object_class_find_property (G_OBJECT_GET_CLASS (state->series_pt), "separation"))
-		g_object_set (state->series_pt, "separation", (double)sep / 100., NULL);
-}
-
-static void
-xlsx_chart_style_start (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	if (NULL != state->cur_obj &&
-	    GOG_IS_STYLED_OBJECT (state->cur_obj) &&
-	    NULL == state->marker) {
-		g_return_if_fail (state->cur_style == NULL);
-		state->cur_style = go_style_dup (
-			go_styled_object_get_style (GO_STYLED_OBJECT (state->cur_obj)));
-	}
-}
-static void
-xlsx_chart_style_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-
-	if (NULL != state->cur_style) {
-		go_styled_object_set_style (GO_STYLED_OBJECT (state->cur_obj),
-			state->cur_style);
-		g_object_unref (state->cur_style);
-		state->cur_style = NULL;
-	}
-}
-static void
-xlsx_style_line_start (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	state->sp_type |= GO_STYLE_LINE;
-}
-
-static void
-xlsx_style_line_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	state->sp_type &= ~GO_STYLE_LINE;
-}
-
-static void
-xlsx_chart_no_fill (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	if (NULL != state->marker)
-		;
-	else if (NULL != state->cur_style) {
-		if (!(state->sp_type & GO_STYLE_LINE)) {
-			state->cur_style->fill.type = GO_STYLE_FILL_NONE;
-			state->cur_style->fill.auto_type = FALSE;
-		}
-	}
-}
-static void
-xlsx_chart_solid_fill (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	if (NULL != state->marker)
-		;
-	else if (NULL != state->cur_style) {
-		if (!(state->sp_type & GO_STYLE_LINE)) {
-			state->cur_style->fill.type = GO_STYLE_FILL_PATTERN;
-			state->cur_style->fill.auto_type = FALSE;
-		}
-	}
-}
-
-static void
-xlsx_draw_color_themed (GsfXMLIn *xin, xmlChar const **attrs)
-{
-#if 0
-	static EnumVal const colors[] = {
-		{ "bg1",	 0 }, /* Background Color 1 */
-		{ "tx1",	 1 }, /* Text Color 1 */
-		{ "bg2",	 2 }, /* Background Color 2 */
-		{ "tx2",	 3 }, /* Text Color 2 */
-		{ "accent1",	 4 }, /* Accent Color 1 */
-		{ "accent2",	 5 }, /* Accent Color 2 */
-		{ "accent3",	 6 }, /* Accent Color 3 */
-		{ "accent4",	 7 }, /* Accent Color 4 */
-		{ "accent5",	 8 }, /* Accent Color 5 */
-		{ "accent6",	 9 }, /* Accent Color 6 */
-		{ "hlink",	10 }, /* Hyperlink Color */
-		{ "folHlink",	11 }, /* Followed Hyperlink Color */
-		{ "phClr",	12 }, /* Style Color */
-		{ "dk1",	13 }, /* Dark Color 1 */
-		{ "lt1",	14 }, /* Light Color 1 */
-		{ "dk2",	15 }, /* Dark Color 2 */
-		{ "lt2",	16 }, /* Light Color 2 */
-		{ NULL, 0 }
-	};
-#endif
-
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	gpointer val = NULL;
-	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
-		if (0 == strcmp (attrs[0], "val")) {
-			val = g_hash_table_lookup (state->theme_colors_by_name, attrs[1]);
-			if (NULL == val)
-				xlsx_warning (xin, _("Unknown color '%s'"), attrs[1]);
-		}
-
-	state->gocolor = GPOINTER_TO_UINT (val);
-}
-
-static void
-xlsx_draw_color_rgb (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	if (NULL == state->cur_style)
-		return;
-	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
-		if (attr_gocolor (xin, attrs, "val", &state->gocolor))
-			;
-}
-
-static void
-xlsx_draw_color_alpha (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	int val;
-	if (simple_int (xin, attrs, &val)) {
-		int level = 255 * val / 100000;
-		state->gocolor = GO_COLOR_CHANGE_A (state->gocolor, level);
-	}
-}
-
-static void
-xlsx_draw_color_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	if (NULL != state->marker)
-		go_marker_set_fill_color (state->marker, state->gocolor);
-	else if (NULL != state->cur_style) {
-		if (state->sp_type & GO_STYLE_LINE) {
-			state->cur_style->line.color = state->gocolor;
-			state->cur_style->line.auto_color = FALSE;
-		} else {
-			state->cur_style->fill.pattern.back = state->gocolor;
-			state->cur_style->fill.pattern.fore = state->gocolor;
-			state->cur_style->fill.auto_fore = FALSE;
-			state->cur_style->fill.auto_back = FALSE;
-		}
-	}
-}
-
-static void
-xlsx_draw_line_dash (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	static EnumVal const dashes[] = {
-		{ "solid",		GO_LINE_SOLID },
-		{ "dot",		GO_LINE_DOT },
-		{ "dash",		GO_LINE_DASH },
-		{ "lgDash",		GO_LINE_LONG_DASH },
-		{ "dashDot",		GO_LINE_DASH_DOT },
-		{ "lgDashDot",		GO_LINE_DASH_DOT_DOT },
-		{ "lgDashDotDot",	GO_LINE_DASH_DOT_DOT_DOT },
-		{ "sysDash",		GO_LINE_S_DASH },
-		{ "sysDot",		GO_LINE_S_DOT },
-		{ "sysDashDot",		GO_LINE_S_DASH_DOT },
-		{ "sysDashDotDot",	GO_LINE_S_DASH_DOT_DOT },
-		{ NULL, 0 }
-	};
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	int dash;
-
-	if (!simple_enum (xin, attrs, dashes, &dash))
-		return;
-
-	if (NULL != state->marker)
-		; /* what goes here ?*/
-	else if (NULL != state->cur_style) {
-		if (state->sp_type & GO_STYLE_LINE) {
-			state->cur_style->line.auto_dash = FALSE;
-			state->cur_style->line.dash_type = dash;
-		} else {
-			; /* what goes here ?*/
-		}
-	}
-}
-
-static void
-xlsx_chart_marker_start (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	state->marker = go_marker_new ();
-	state->marker_symbol = GO_MARKER_MAX;
-}
-
-static void
-xlsx_chart_marker_symbol (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	static EnumVal const symbols[] = {
-		{ "circle",	GO_MARKER_CIRCLE },
-		{ "dash",	GO_MARKER_BAR },		/* FIXME */
-		{ "diamond",	GO_MARKER_DIAMOND },
-		{ "dot",	GO_MARKER_HALF_BAR },		/* FIXME */
-		{ "none",	GO_MARKER_NONE },
-		{ "plus",	GO_MARKER_CROSS },		/* CHECK ME */
-		{ "square",	GO_MARKER_SQUARE },
-		{ "star",	GO_MARKER_ASTERISK },		/* CHECK ME */
-		{ "triangle",	GO_MARKER_TRIANGLE_UP },	/* FIXME */
-		{ "x",		GO_MARKER_X },
-		{ NULL, 0 }
-	};
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	int symbol;
-	if (NULL != state->marker && simple_enum (xin, attrs, symbols, &symbol))
-		state->marker_symbol = symbol;
-}
-
-static void
-xlsx_chart_marker_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	if (NULL != state->cur_obj && GOG_IS_STYLED_OBJECT (state->cur_obj)) {
-		GOStyle *style = go_styled_object_get_style (
-			GO_STYLED_OBJECT (state->cur_obj));
-		if (state->marker_symbol != GO_MARKER_MAX) {
-			style->marker.auto_shape = FALSE;
-			go_marker_set_shape (state->marker, state->marker_symbol);
-		}
-		go_style_set_marker (style, state->marker);
-		state->marker = NULL;
-	}
-}
-
-static void
-xlsx_chart_text_start (GsfXMLIn *xin, G_GNUC_UNUSED xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	if (NULL == state->series) { /* Hmm, why? */
-		GogObject *label = gog_object_add_by_name (state->cur_obj,
-			(state->cur_obj == (GogObject *)state->chart) ? "Title" : "Label", NULL);
-		xlsx_chart_push_obj (state, label);
-	}
-}
-
-static void
-xlsx_chart_text (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-
-	if (NULL == state->series) {
-		if (state->cur_obj && state->chart_tx) {
-			GnmValue *value = value_new_string_nocopy (state->chart_tx);
-			GnmExprTop const *texpr = gnm_expr_top_new_constant (value);
-			gog_dataset_set_dim (GOG_DATASET (state->cur_obj), 0,
-				gnm_go_data_scalar_new_expr (state->sheet, texpr), NULL);
-			state->chart_tx = NULL;
-		}
-		xlsx_chart_pop_obj (state);
-	}
-	g_free (state->chart_tx);
-	state->chart_tx = NULL;
-}
-
-static void
-xlsx_chart_p_start (GsfXMLIn *xin, G_GNUC_UNUSED xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	if (state->chart_tx) {
-		char *buf = g_strconcat (state->chart_tx, "\n", NULL);
-		g_free (state->chart_tx);
-		state->chart_tx = buf;
-	}
-}
-
-static void
-xlsx_chart_text_content (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	/* a rich node can contain several t children, if this happens, concatenate
-	 the contents */
-	if (state->chart_tx) {
-		char *buf = g_strconcat (state->chart_tx, xin->content->str, NULL);
-		g_free (state->chart_tx);
-		state->chart_tx = buf;
-	} else
-		state->chart_tx = g_strdup (xin->content->str);
-}
-
-static void
-xlsx_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState *state = (XLSXReadState *)xin->user_state;
-	GogObject *backplane = gog_object_add_by_name (
-		GOG_OBJECT (state->chart), "Backplane", NULL);
-	xlsx_chart_push_obj (state, backplane);
-}
-static void
-xlsx_chart_pop (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	xlsx_chart_pop_obj ((XLSXReadState *)xin->user_state);
-}
-
-static GsfXMLInNode const xlsx_chart_dtd[] =
-{
-GSF_XML_IN_NODE_FULL (START, START, -1, NULL, GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
-GSF_XML_IN_NODE_FULL (START, CHART_SPACE, XL_NS_CHART, "chartSpace", GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
-  GSF_XML_IN_NODE (CHART_SPACE, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, &xlsx_chart_style_start, &xlsx_chart_style_end),
-    GSF_XML_IN_NODE (SHAPE_PR, SP_XFRM, XL_NS_DRAW, "xfrm", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (SP_XFRM, SP_XFRM_OFF, XL_NS_DRAW, "off", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (SP_XFRM, SP_XFRM_EXT, XL_NS_DRAW, "ext", GSF_XML_NO_CONTENT, NULL, NULL),
-    GSF_XML_IN_NODE (SHAPE_PR, SP_PR_PRST_GEOM, XL_NS_DRAW, "prstGeom", GSF_XML_NO_CONTENT, NULL, NULL),
-    GSF_XML_IN_NODE (SHAPE_PR, FILL_NONE,	XL_NS_DRAW, "noFill", GSF_XML_NO_CONTENT, &xlsx_chart_no_fill, NULL),
-    GSF_XML_IN_NODE (SHAPE_PR, FILL_SOLID,	XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, &xlsx_chart_solid_fill, NULL),
-      GSF_XML_IN_NODE (FILL_SOLID, COLOR_THEMED, XL_NS_DRAW, "schemeClr", GSF_XML_NO_CONTENT, &xlsx_draw_color_themed, &xlsx_draw_color_end),
-        GSF_XML_IN_NODE (COLOR_THEMED, COLOR_LUM, XL_NS_DRAW, "lumMod", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (FILL_SOLID, COLOR_RGB,	 XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, &xlsx_draw_color_rgb, &xlsx_draw_color_end),
-        GSF_XML_IN_NODE (COLOR_RGB, RGB_ALPHA,	   XL_NS_DRAW, "alpha", GSF_XML_NO_CONTENT, &xlsx_draw_color_alpha, NULL),
-        GSF_XML_IN_NODE (COLOR_RGB, RGB_GAMMA,	   XL_NS_DRAW, "gamma", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (COLOR_RGB, RGB_INV_GAMMA, XL_NS_DRAW, "invGamma", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (COLOR_RGB, RGB_SHADE,	   XL_NS_DRAW, "shade", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (COLOR_RGB, RGB_TINT,	   XL_NS_DRAW, "tint", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (COLOR_RGB, LN_DASH,	   XL_NS_DRAW, "prstDash", GSF_XML_NO_CONTENT, &xlsx_draw_line_dash, NULL),
-
-    GSF_XML_IN_NODE (SHAPE_PR, FILL_BLIP,	XL_NS_DRAW, "blipFill", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_BLIP,	XL_NS_DRAW, "blip", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_SRC,	XL_NS_DRAW, "srcRect", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_TILE,	XL_NS_DRAW, "tile", GSF_XML_NO_CONTENT, NULL, NULL),
-
-    GSF_XML_IN_NODE (SHAPE_PR, FILL_GRAD,	XL_NS_DRAW, "gradFill", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (FILL_GRAD, GRAD_LIST,	XL_NS_DRAW, "gsLst", GSF_XML_NO_CONTENT, NULL, NULL),
-       GSF_XML_IN_NODE (GRAD_LIST, GRAD_LIST_ITEM, XL_NS_DRAW, "gs", GSF_XML_NO_CONTENT, NULL, NULL),
-         GSF_XML_IN_NODE (GRAD_LIST_ITEM, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-      GSF_XML_IN_NODE (FILL_GRAD, GRAD_LINE,	XL_NS_DRAW, "lin", GSF_XML_NO_CONTENT, NULL, NULL),
-
-    GSF_XML_IN_NODE (SHAPE_PR, FILL_PATT,	XL_NS_DRAW, "pattFill", GSF_XML_NO_CONTENT, &xlsx_chart_solid_fill, NULL),
-      GSF_XML_IN_NODE (FILL_PATT, FILL_PATT_BG,	XL_NS_DRAW, "bgClr", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (FILL_PATT_BG, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-      GSF_XML_IN_NODE (FILL_PATT, FILL_PATT_FG,	XL_NS_DRAW, "fgClr", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (FILL_PATT_FG, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-
-    GSF_XML_IN_NODE (SHAPE_PR, SHAPE_PR_LN, XL_NS_DRAW, "ln", GSF_XML_NO_CONTENT, &xlsx_style_line_start, &xlsx_style_line_end),
-      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_NOFILL, XL_NS_DRAW, "noFill", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_DASH, XL_NS_DRAW, "prstDash", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-      GSF_XML_IN_NODE (SHAPE_PR_LN, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-      GSF_XML_IN_NODE (SHAPE_PR_LN, FILL_PATT,	XL_NS_DRAW, "pattFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_MITER,	XL_NS_DRAW, "miter", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_ROUND,	XL_NS_DRAW, "round", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_HEAD,	XL_NS_DRAW, "headEnd", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (SHAPE_PR_LN, LN_TAIL,	XL_NS_DRAW, "tailEnd", GSF_XML_NO_CONTENT, NULL, NULL),
-    GSF_XML_IN_NODE (SHAPE_PR, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_BODY,	XL_NS_DRAW, "bodyPr", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_STYLE,	XL_NS_DRAW, "lstStyle", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_P,	XL_NS_DRAW, "p", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (TEXT_PR_P, PR_P_PR,	XL_NS_DRAW, "pPr", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (PR_P_PR, PR_P_PR_DEF, XL_NS_DRAW, "defRPr", GSF_XML_NO_CONTENT, NULL, NULL),
-            GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_CS, XL_NS_DRAW, "cs", GSF_XML_NO_CONTENT, NULL, NULL),
-            GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_EA, XL_NS_DRAW, "ea", GSF_XML_NO_CONTENT, NULL, NULL),
-            GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_LATIN, XL_NS_DRAW, "latin", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (PR_P_PR_DEF, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-            GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_UFILLTX, XL_NS_DRAW, "uFillTx", GSF_XML_NO_CONTENT, NULL, NULL),
-            GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_ULNTX, XL_NS_DRAW, "uLnTx", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (TEXT_PR_P, PR_P_PR_END,XL_NS_DRAW, "endParaRPr", GSF_XML_NO_CONTENT, NULL, NULL),
-
-  GSF_XML_IN_NODE (CHART_SPACE, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-
-  GSF_XML_IN_NODE (CHART_SPACE, CHART, XL_NS_CHART, "chart", GSF_XML_NO_CONTENT, NULL, NULL),
-    GSF_XML_IN_NODE (CHART, PLOTAREA, XL_NS_CHART, "plotArea", GSF_XML_NO_CONTENT, &xlsx_plot_area, &xlsx_chart_pop),
-      GSF_XML_IN_NODE (PLOTAREA, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-      GSF_XML_IN_NODE_FULL (PLOTAREA, CAT_AXIS, XL_NS_CHART, "catAx", GSF_XML_NO_CONTENT, FALSE, TRUE,
-			    &xlsx_axis_start, &xlsx_axis_end, XLSX_AXIS_CAT),
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_AXID, XL_NS_CHART, "axId", GSF_XML_NO_CONTENT, &xlsx_axis_id, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_DELETE, XL_NS_CHART, "delete", GSF_XML_NO_CONTENT, &xlsx_axis_delete, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_NUMFMT, XL_NS_CHART, "numFmt", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_DELETE, XL_NS_CHART, "delete", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_MAJORTICKMARK, XL_NS_CHART, "majorTickMark", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_MINORTICKMARK, XL_NS_CHART, "minorTickMark", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE_FULL (CAT_AXIS, AXIS_MAJORTICK_UNIT, XL_NS_CHART, "majorUnit", GSF_XML_NO_CONTENT, FALSE, TRUE,
-			      &xlsx_axis_bound, NULL, GOG_AXIS_ELEM_MAJOR_TICK),
-        GSF_XML_IN_NODE_FULL (CAT_AXIS, AXIS_MINORTICK_UNIT, XL_NS_CHART, "minorUnit", GSF_XML_NO_CONTENT, FALSE, TRUE,
-			      &xlsx_axis_bound, NULL, GOG_AXIS_ELEM_MINOR_TICK),
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_TICK_LBL_SKIP, XL_NS_CHART, "tickLblSkip", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_TICK_MARK_SKIP, XL_NS_CHART, "tickMarkSkip", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_SCALING, XL_NS_CHART, "scaling", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE_FULL (AXIS_SCALING, AX_MIN, XL_NS_CHART, "min", GSF_XML_NO_CONTENT, FALSE, TRUE,
-				&xlsx_axis_bound, NULL, GOG_AXIS_ELEM_MIN),
-          GSF_XML_IN_NODE_FULL (AXIS_SCALING, AX_MAX, XL_NS_CHART, "max", GSF_XML_NO_CONTENT, FALSE, TRUE,
-				&xlsx_axis_bound, NULL, GOG_AXIS_ELEM_MAX),
-          GSF_XML_IN_NODE (AXIS_SCALING, AX_LOG, XL_NS_CHART, "logBase", GSF_XML_NO_CONTENT, &xlsx_chart_logbase, NULL),
-          GSF_XML_IN_NODE (AXIS_SCALING, AX_ORIENTATION, XL_NS_CHART, "orientation", GSF_XML_NO_CONTENT, &xlsx_axis_orientation, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, MAJOR_GRID, XL_NS_CHART, "majorGridlines", GSF_XML_NO_CONTENT,
-			 &xlsx_chart_gridlines, &xlsx_chart_pop),
-          GSF_XML_IN_NODE (MAJOR_GRID, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_POS, XL_NS_CHART, "axPos", GSF_XML_NO_CONTENT, &xlsx_axis_pos, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_TICKLBLPOS, XL_NS_CHART, "tickLblPos", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_AUTO, XL_NS_CHART, "auto", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_CROSSAX, XL_NS_CHART, "crossAx", GSF_XML_NO_CONTENT, &xlsx_axis_crossax, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_CROSSES, XL_NS_CHART, "crosses", GSF_XML_NO_CONTENT, &xlsx_axis_crosses, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, AXIS_CROSSES_AT, XL_NS_CHART, "crossesAt", GSF_XML_NO_CONTENT, &xlsx_axis_crosses_at, NULL),
-
-        GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_LBLALGN, XL_NS_CHART, "lblAlgn", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_LBLOFFSET, XL_NS_CHART, "lblOffset", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (CAT_AXIS, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (CAT_AXIS, TITLE, XL_NS_CHART, "title", GSF_XML_NO_CONTENT, NULL, NULL),		/* ID is used */
-          GSF_XML_IN_NODE (TITLE, LAYOUT, XL_NS_CHART, "layout", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (LAYOUT, LAST_LAYOUT,	    XL_NS_CHART, "lastLayout", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (LAYOUT, LAST_LAYOUT_OUTER, XL_NS_CHART, "lastLayoutOuter", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (LAYOUT, MAN_LAYOUT, XL_NS_CHART, "manualLayout", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_TARGET, XL_NS_CHART, "layoutTarget", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_XMODE, XL_NS_CHART, "xMode", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_YMODE, XL_NS_CHART, "yMode", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (TITLE, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-          GSF_XML_IN_NODE (TITLE, TEXT, XL_NS_CHART, "tx", GSF_XML_NO_CONTENT, &xlsx_chart_text_start, &xlsx_chart_text),
-            GSF_XML_IN_NODE (TEXT, TX_RICH, XL_NS_CHART, "rich", GSF_XML_NO_CONTENT, NULL, NULL),
-              GSF_XML_IN_NODE (TX_RICH, TX_RICH_BODY, XL_NS_CHART, "bodyP", GSF_XML_NO_CONTENT, NULL, NULL),
-              GSF_XML_IN_NODE (TX_RICH, TX_RICH_BODY_PR, XL_NS_DRAW, "bodyPr", GSF_XML_NO_CONTENT, NULL, NULL),
-              GSF_XML_IN_NODE (TX_RICH, TX_RICH_STYLES, XL_NS_DRAW, "lstStyle", GSF_XML_NO_CONTENT, NULL, NULL),
-              GSF_XML_IN_NODE (TX_RICH, TX_RICH_P, XL_NS_DRAW, "p", GSF_XML_NO_CONTENT, &xlsx_chart_p_start, NULL),
-                GSF_XML_IN_NODE (TX_RICH_P, PR_P_PR, XL_NS_DRAW, "pPr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-                GSF_XML_IN_NODE (TX_RICH_P, TX_RICH_R, XL_NS_DRAW, "r", GSF_XML_NO_CONTENT, NULL, NULL),
-                  GSF_XML_IN_NODE (TX_RICH_R, TX_RICH_R_PR, XL_NS_DRAW, "rPr", GSF_XML_NO_CONTENT, NULL, NULL),
-		    GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_CS, XL_NS_DRAW, "cs", GSF_XML_NO_CONTENT, NULL, NULL),
-		    GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_EA, XL_NS_DRAW, "ea", GSF_XML_NO_CONTENT, NULL, NULL),
-		    GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_LATIN, XL_NS_DRAW, "latin", GSF_XML_NO_CONTENT, NULL, NULL),
-		    GSF_XML_IN_NODE (TX_RICH_R_PR, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-		    GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_UFILLTX, XL_NS_DRAW, "uFillTx", GSF_XML_NO_CONTENT, NULL, NULL),
-		    GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_ULNTX, XL_NS_DRAW, "uLnTx", GSF_XML_NO_CONTENT, NULL, NULL),
-                  GSF_XML_IN_NODE (TX_RICH_R, TX_RICH_R_T, XL_NS_DRAW,  "t", GSF_XML_CONTENT, NULL, &xlsx_chart_text_content),
-            GSF_XML_IN_NODE (TEXT, STR_REF, XL_NS_CHART, "strRef", GSF_XML_NO_CONTENT, NULL, NULL),
-              GSF_XML_IN_NODE (STR_REF, FUNC,	XL_NS_CHART,	"f",	GSF_XML_CONTENT, NULL, &xlsx_chart_ser_f),
-              GSF_XML_IN_NODE (STR_REF, STR_CACHE, XL_NS_CHART,	"strCache", GSF_XML_NO_CONTENT, NULL, NULL),
-                GSF_XML_IN_NODE (STR_CACHE, STR_CACHE_COUNT, XL_NS_CHART,"ptCount", GSF_XML_NO_CONTENT, NULL, NULL),
-                GSF_XML_IN_NODE (STR_CACHE, STR_PT, XL_NS_CHART,"pt", GSF_XML_NO_CONTENT, NULL, NULL),
-                  GSF_XML_IN_NODE (STR_PT, STR_VAL, XL_NS_CHART,"v", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (TITLE, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-
-      GSF_XML_IN_NODE_FULL (PLOTAREA, VAL_AXIS, XL_NS_CHART, "valAx", GSF_XML_NO_CONTENT, FALSE, TRUE,
-			    &xlsx_axis_start, &xlsx_axis_end, XLSX_AXIS_VAL),
-	GSF_XML_IN_NODE (VAL_AXIS, AXIS_AXID, XL_NS_CHART, "axId", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, AXIS_DELETE, XL_NS_CHART, "delete", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, TITLE, XL_NS_CHART, "title", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, AXIS_SCALING, XL_NS_CHART, "scaling", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, AXIS_POS, XL_NS_CHART, "axPos", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, MAJOR_GRID, XL_NS_CHART, "majorGridlines", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, AXIS_NUMFMT, XL_NS_CHART, "numFmt", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, AXIS_MAJORTICKMARK, XL_NS_CHART, "majorTickMark", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, AXIS_MINORTICKMARK, XL_NS_CHART, "minorTickMark", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (VAL_AXIS, AXIS_MAJORTICK_UNIT, XL_NS_CHART, "majorUnit", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (VAL_AXIS, AXIS_MINORTICK_UNIT, XL_NS_CHART, "minorUnit", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (VAL_AXIS, VAL_AXIS_TICKLBLPOS, XL_NS_CHART, "tickLblPos", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, AXIS_CROSSAX, XL_NS_CHART, "crossAx", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, AXIS_CROSSES, XL_NS_CHART, "crosses", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, AXIS_CROSSES_AT, XL_NS_CHART, "crossesAt", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, VAL_AXIS_CROSSBETWEEN, XL_NS_CHART, "crossBetween", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (VAL_AXIS, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (VAL_AXIS, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-
-      GSF_XML_IN_NODE_FULL (PLOTAREA, DATE_AXIS, XL_NS_CHART, "dateAx", GSF_XML_NO_CONTENT, FALSE, TRUE,
-                            &xlsx_axis_start, &xlsx_axis_end, XLSX_AXIS_DATE),
-        GSF_XML_IN_NODE (DATE_AXIS, AXIS_AUTO, XL_NS_CHART, "auto", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (DATE_AXIS, AXIS_AXID, XL_NS_CHART, "axId", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (DATE_AXIS, AXIS_POS, XL_NS_CHART, "axPos", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (DATE_AXIS, AXIS_CROSSAX, XL_NS_CHART, "crossAx", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (DATE_AXIS, AXIS_CROSSES, XL_NS_CHART, "crosses", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (DATE_AXIS, AXIS_CROSSES_AT, XL_NS_CHART, "crossesAt", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (DATE_AXIS, AXIS_DELETE, XL_NS_CHART, "delete", GSF_XML_NO_CONTENT, NULL, NULL),
-	
-      GSF_XML_IN_NODE (PLOTAREA, LAYOUT, XL_NS_CHART, "layout", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (LAYOUT, LAST_LAYOUT,	    XL_NS_CHART, "lastLayout", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (LAST_LAYOUT, LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (LAYOUT, LAST_LAYOUT_OUTER, XL_NS_CHART, "lastLayoutOuter", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (LAST_LAYOUT_OUTER, LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (LAYOUT, MAN_LAYOUT, XL_NS_CHART, "manualLayout", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_H, XL_NS_CHART, "h", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_W, XL_NS_CHART, "w", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_X, XL_NS_CHART, "x", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_XMODE, XL_NS_CHART, "xMode", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_Y, XL_NS_CHART, "y", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (MAN_LAYOUT, MAN_LAYOUT_YMODE, XL_NS_CHART, "yMode", GSF_XML_NO_CONTENT, NULL, NULL),
-
-      GSF_XML_IN_NODE (PLOTAREA, SCATTER, XL_NS_CHART,	"scatterChart", GSF_XML_NO_CONTENT, xlsx_chart_xy, &xlsx_plot_end),
-        GSF_XML_IN_NODE (SCATTER, SCATTER_STYLE, XL_NS_CHART,	"scatterStyle", GSF_XML_NO_CONTENT, &xlsx_scatter_style, NULL),
-        GSF_XML_IN_NODE (SCATTER, PLOT_AXIS_ID, XL_NS_CHART,           "axId", GSF_XML_NO_CONTENT, &xlsx_plot_axis_id, NULL),
-
-        GSF_XML_IN_NODE (SCATTER, SERIES, XL_NS_CHART,	"ser", GSF_XML_NO_CONTENT, &xlsx_chart_ser_start, &xlsx_chart_ser_end),
-          GSF_XML_IN_NODE (SERIES, SERIES_IDX, XL_NS_CHART,	"idx", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (SERIES, SERIES_ORDER, XL_NS_CHART,	"order", GSF_XML_NO_CONTENT, NULL, NULL),
-
-          GSF_XML_IN_NODE_FULL (SERIES, SERIES_CAT, XL_NS_CHART,"cat", GSF_XML_NO_CONTENT, FALSE, TRUE,
-			   &xlsx_ser_type_start, &xlsx_ser_type_end, GOG_MS_DIM_CATEGORIES),
-            GSF_XML_IN_NODE (SERIES_CAT, STR_REF, XL_NS_CHART,	"strRef", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-            GSF_XML_IN_NODE (SERIES_CAT, NUM_LIT, XL_NS_CHART,  "numLit", GSF_XML_NO_CONTENT, NULL, NULL),
-              GSF_XML_IN_NODE (NUM_LIT, NUM_LIT_FMT, XL_NS_CHART,   "formatCode", GSF_XML_NO_CONTENT, NULL, NULL),
-              GSF_XML_IN_NODE (NUM_LIT, NUM_LIT_COUNT, XL_NS_CHART, "ptCount", GSF_XML_NO_CONTENT, NULL, NULL),
-              GSF_XML_IN_NODE (NUM_LIT, NUM_LIT_PT, XL_NS_CHART,     "pt", GSF_XML_NO_CONTENT, NULL, NULL),
-                GSF_XML_IN_NODE (NUM_LIT_PT, NUM_LIT_PT_VAL, XL_NS_CHART,     "v", GSF_XML_NO_CONTENT, NULL, NULL),
-            GSF_XML_IN_NODE (SERIES_CAT, NUM_REF, XL_NS_CHART,	"numRef", GSF_XML_NO_CONTENT, NULL, NULL),
-              GSF_XML_IN_NODE (NUM_REF, FUNC, XL_NS_CHART,	"f", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-              GSF_XML_IN_NODE (NUM_REF, NUM_CACHE, XL_NS_CHART,	"numCache", GSF_XML_NO_CONTENT, NULL, NULL),
-                GSF_XML_IN_NODE (NUM_CACHE, NUM_CACHE_FMT, XL_NS_CHART,	 "formatCode", GSF_XML_NO_CONTENT, NULL, NULL),
-                GSF_XML_IN_NODE (NUM_CACHE, NUM_CACHE_COUNT, XL_NS_CHART,"ptCount", GSF_XML_NO_CONTENT, NULL, NULL),
-                GSF_XML_IN_NODE (NUM_CACHE, NUM_PT, XL_NS_CHART,"pt", GSF_XML_NO_CONTENT, NULL, NULL),
-                  GSF_XML_IN_NODE (NUM_PT, NUM_VAL, XL_NS_CHART,"v", GSF_XML_NO_CONTENT, NULL, NULL),
-
-          GSF_XML_IN_NODE_FULL (SERIES, SERIES_VAL, XL_NS_CHART,	"val", GSF_XML_NO_CONTENT, FALSE, TRUE,
-			   &xlsx_ser_type_start, &xlsx_ser_type_end, GOG_MS_DIM_VALUES),
-            GSF_XML_IN_NODE (SERIES_VAL, NUM_REF, XL_NS_CHART,	"numRef", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-
-          GSF_XML_IN_NODE_FULL (SERIES, SERIES_X_VAL, XL_NS_CHART,	"xVal", GSF_XML_NO_CONTENT, FALSE, TRUE,
-			   &xlsx_ser_type_start, &xlsx_ser_type_end, GOG_MS_DIM_CATEGORIES),
-            GSF_XML_IN_NODE (SERIES_X_VAL, NUM_REF, XL_NS_CHART,	"numRef", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-            GSF_XML_IN_NODE (SERIES_X_VAL, NUM_LIT, XL_NS_CHART,	"numLit", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-
-          GSF_XML_IN_NODE_FULL (SERIES, SERIES_Y_VAL, XL_NS_CHART,	"yVal", GSF_XML_NO_CONTENT, FALSE, TRUE,
-			   &xlsx_ser_type_start, &xlsx_ser_type_end, GOG_MS_DIM_VALUES),
-            GSF_XML_IN_NODE (SERIES_Y_VAL, NUM_REF, XL_NS_CHART,	"numRef", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-            GSF_XML_IN_NODE (SERIES_Y_VAL, NUM_LIT, XL_NS_CHART,	"numLit", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-
-          GSF_XML_IN_NODE_FULL (SERIES, SERIES_BUBBLES, XL_NS_CHART,	"bubbleSize", GSF_XML_NO_CONTENT, FALSE, TRUE,
-			   &xlsx_ser_type_start, &xlsx_ser_type_end, GOG_MS_DIM_BUBBLES),
-            GSF_XML_IN_NODE (SERIES_BUBBLES, NUM_REF, XL_NS_CHART,	"numRef", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-            GSF_XML_IN_NODE (SERIES_BUBBLES, NUM_LIT, XL_NS_CHART,	"numLit", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-
-          GSF_XML_IN_NODE (SERIES, TEXT, XL_NS_CHART,	"tx", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-
-          GSF_XML_IN_NODE (SERIES, SERIES_BUBBLES_3D, XL_NS_CHART,	"bubble3D", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (SERIES, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-          GSF_XML_IN_NODE (SERIES, SERIES_SMOOTH, XL_NS_CHART, "smooth", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (SERIES, SERIES_IDX, XL_NS_CHART,	"idx", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (SERIES, SERIES_D_LBLS, XL_NS_CHART,	"dLbls", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (SERIES_D_LBLS, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-	    GSF_XML_IN_NODE (SERIES_D_LBLS, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-	    GSF_XML_IN_NODE (SERIES_D_LBLS, SHOW_VAL, XL_NS_CHART, "showVal", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (SERIES_D_LBLS, NUM_FMT, XL_NS_CHART, "numFmt", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (SERIES_D_LBLS, SHOW_BUBBLE, XL_NS_CHART, "showBubbleSize", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (SERIES_D_LBLS, SHOW_CAT_NAME, XL_NS_CHART, "showCatName", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (SERIES_D_LBLS, SHOW_LEADERS, XL_NS_CHART, "showLeaderLines", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (SERIES_D_LBLS, SHOW_PERCENT, XL_NS_CHART, "showPercent", GSF_XML_NO_CONTENT, NULL, NULL),
-
-          GSF_XML_IN_NODE (SERIES, SERIES_PT, XL_NS_CHART,	"dPt", GSF_XML_NO_CONTENT, &xlsx_chart_pt_start, &xlsx_chart_pt_end),
-            GSF_XML_IN_NODE (SERIES_PT, PT_IDX, XL_NS_CHART,	"idx", GSF_XML_NO_CONTENT, &xlsx_chart_pt_index, NULL),
-            GSF_XML_IN_NODE (SERIES_PT, SHAPE_PR, XL_NS_CHART,	"spPr", GSF_XML_NO_CONTENT, NULL, NULL),
-            GSF_XML_IN_NODE (SERIES_PT, PT_SEP, XL_NS_CHART,	"explosion", GSF_XML_NO_CONTENT, &xlsx_chart_pt_sep, NULL),
-            GSF_XML_IN_NODE (SERIES_PT, MARKER, XL_NS_CHART,	"marker", GSF_XML_NO_CONTENT, &xlsx_chart_marker_start, &xlsx_chart_marker_end),
-              GSF_XML_IN_NODE (MARKER, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-              GSF_XML_IN_NODE (MARKER, MARKER_SYMBOL, XL_NS_CHART, "symbol", GSF_XML_NO_CONTENT, &xlsx_chart_marker_symbol, NULL),
-              GSF_XML_IN_NODE (MARKER, MARKER_SIZE, XL_NS_CHART, "size", GSF_XML_NO_CONTENT, NULL, NULL),
-
-          GSF_XML_IN_NODE (SERIES, SERIES_ERR_BARS, XL_NS_CHART,"errBars", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SERIES_ERR_BARS_ERRBARTYPE, XL_NS_CHART, "errBarType",  GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SERIES_ERR_BARS_ERRDIR, XL_NS_CHART, "errDir", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SERIES_ERR_BARS_ERRVALTYPE, XL_NS_CHART, "errValType", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SERIES_ERR_BARS_MINUS, XL_NS_CHART, "minus", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (SERIES_ERR_BARS_MINUS, NUM_REF, XL_NS_CHART, "numRef", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-              GSF_XML_IN_NODE (SERIES_ERR_BARS_MINUS, NUM_LIT, XL_NS_CHART, "numLit", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SERIES_ERR_BARS_PLUS, XL_NS_CHART, "plus", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (SERIES_ERR_BARS_PLUS, NUM_REF, XL_NS_CHART, "numRef", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-              GSF_XML_IN_NODE (SERIES_ERR_BARS_PLUS, NUM_LIT, XL_NS_CHART, "numLit", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-	    GSF_XML_IN_NODE (SERIES_ERR_BARS, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-
-      GSF_XML_IN_NODE (PLOTAREA, BUBBLE, XL_NS_CHART,	"bubbleChart", GSF_XML_NO_CONTENT, &xlsx_chart_bubble, &xlsx_plot_end),
-        GSF_XML_IN_NODE (BUBBLE, PLOT_AXIS_ID, XL_NS_CHART,	"axId", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (BUBBLE, SERIES, XL_NS_CHART,		"ser", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (BUBBLE, BUBBLE_SCALE, XL_NS_CHART,	"bubbleScale", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (BUBBLE, BUBBLE_NEGATIVES, XL_NS_CHART,	"showNegBubbles", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (BUBBLE, BUBBLE_SIZE_REP, XL_NS_CHART,	"sizeRepresents", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (BUBBLE, VARY_COLORS, XL_NS_CHART,	"varyColors", GSF_XML_NO_CONTENT, &xlsx_vary_colors, NULL),
-
-      GSF_XML_IN_NODE (PLOTAREA, BARCOL, XL_NS_CHART,	"barChart", GSF_XML_NO_CONTENT, &xlsx_chart_bar, &xlsx_plot_end),
-        GSF_XML_IN_NODE (BARCOL, PLOT_AXIS_ID,	XL_NS_CHART, "axId", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (BARCOL, SERIES,	XL_NS_CHART, "ser", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (BARCOL, BARCOL_DIR,	XL_NS_CHART, "barDir", GSF_XML_NO_CONTENT, &xlsx_chart_bar_dir, NULL),
-        GSF_XML_IN_NODE (BARCOL, BARCOL_OVERLAP, XL_NS_CHART,"overlap", GSF_XML_NO_CONTENT, &xlsx_chart_bar_overlap, NULL),
-        GSF_XML_IN_NODE (BARCOL, GROUPING,	XL_NS_CHART, "grouping", GSF_XML_NO_CONTENT, &xlsx_chart_bar_group, NULL),
-        GSF_XML_IN_NODE (BARCOL, GAP_WIDTH,	XL_NS_CHART, "gapWidth", GSF_XML_NO_CONTENT, &xlsx_chart_bar_gap, NULL),
-
-      GSF_XML_IN_NODE (PLOTAREA, LINE, XL_NS_CHART,	"lineChart", GSF_XML_NO_CONTENT, &xlsx_chart_line, &xlsx_plot_end),
-        GSF_XML_IN_NODE (LINE, PLOT_AXIS_ID, XL_NS_CHART,"axId", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-        GSF_XML_IN_NODE (LINE, SERIES, XL_NS_CHART,	"ser", GSF_XML_NO_CONTENT, NULL, NULL),					/* 2nd Def */
-          GSF_XML_IN_NODE (SERIES, MARKER, XL_NS_CHART,	"marker", GSF_XML_NO_CONTENT, NULL, NULL),
-            GSF_XML_IN_NODE (MARKER, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-            GSF_XML_IN_NODE (MARKER, MARKER_SYMBOL, XL_NS_CHART, "symbol", GSF_XML_NO_CONTENT, NULL, NULL),
-            GSF_XML_IN_NODE (MARKER, MARKER_SIZE, XL_NS_CHART, "size", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (LINE, PLOT_AXIS_ID, XL_NS_CHART,"axId", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-        GSF_XML_IN_NODE (LINE, GROUPING, XL_NS_CHART,	"grouping", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-        GSF_XML_IN_NODE (LINE, MARKER, XL_NS_CHART,	"marker", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-
-      GSF_XML_IN_NODE (PLOTAREA, AREA, XL_NS_CHART,	"areaChart", GSF_XML_NO_CONTENT, &xlsx_chart_area, &xlsx_plot_end),
-        GSF_XML_IN_NODE (AREA, PLOT_AXIS_ID, XL_NS_CHART,"axId", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-        GSF_XML_IN_NODE (AREA, SERIES, XL_NS_CHART,	"ser", GSF_XML_NO_CONTENT, NULL, NULL),					/* 2nd Def */
-        GSF_XML_IN_NODE (AREA, GROUPING, XL_NS_CHART,	"grouping", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-
-      GSF_XML_IN_NODE (PLOTAREA, RADAR, XL_NS_CHART,	"radarChart", GSF_XML_NO_CONTENT, &xlsx_chart_radar, &xlsx_plot_end),
-        GSF_XML_IN_NODE (RADAR, PLOT_AXIS_ID, XL_NS_CHART,  "axId", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-        GSF_XML_IN_NODE (RADAR, SERIES, XL_NS_CHART,	  "ser", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-        GSF_XML_IN_NODE (RADAR, RADAR_STYLE, XL_NS_CHART, "radarStyle", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (RADAR, VARY_COLORS, XL_NS_CHART, "varyColors", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-
-      GSF_XML_IN_NODE (PLOTAREA, PIE, XL_NS_CHART,	"pieChart", GSF_XML_NO_CONTENT, &xlsx_chart_pie, &xlsx_plot_end),
-        GSF_XML_IN_NODE (PIE, SERIES, XL_NS_CHART,	"ser", GSF_XML_NO_CONTENT, NULL, NULL),					/* 2nd Def */
-          GSF_XML_IN_NODE (SERIES, PIE_SER_SEP, XL_NS_CHART,	"explosion", GSF_XML_NO_CONTENT, &xlsx_chart_pie_sep, NULL),
-        GSF_XML_IN_NODE (PIE, VARY_COLORS, XL_NS_CHART,	"varyColors", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-        GSF_XML_IN_NODE (PIE, PIE_FIRST_SLICE, XL_NS_CHART,	"firstSliceAng", GSF_XML_NO_CONTENT, NULL, NULL),
-
-      GSF_XML_IN_NODE (PLOTAREA, OF_PIE, XL_NS_CHART,	"ofPieChart", GSF_XML_NO_CONTENT, &xlsx_chart_pie, &xlsx_plot_end),
-        GSF_XML_IN_NODE (OF_PIE, OF_PIE_TYPE,	XL_NS_CHART, "ofPieType", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (OF_PIE, SERIES,	XL_NS_CHART, "ser", GSF_XML_NO_CONTENT, NULL, NULL),				/* 2nd Def */
-        GSF_XML_IN_NODE (OF_PIE, SERIES_LINES,	XL_NS_CHART, "serLines", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (SERIES_LINES, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (OF_PIE, PIE_GAP_WIDTH,	XL_NS_CHART, "gapWidth", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (OF_PIE, VARY_COLORS,	XL_NS_CHART, "varyColors", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (OF_PIE, OF_2ND_PIE,	XL_NS_CHART, "secondPieSize", GSF_XML_NO_CONTENT, NULL, NULL),
-
-      GSF_XML_IN_NODE (PLOTAREA, DOUGHNUT, XL_NS_CHART,	"doughnutChart", GSF_XML_NO_CONTENT, &xlsx_chart_ring, &xlsx_plot_end),
-        GSF_XML_IN_NODE (DOUGHNUT, SERIES, XL_NS_CHART,	"ser", GSF_XML_NO_CONTENT, NULL, NULL),					/* 2nd Def */
-        GSF_XML_IN_NODE (DOUGHNUT, VARY_COLORS, XL_NS_CHART,	"varyColors", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (DOUGHNUT, PIE_FIRST_SLICE, XL_NS_CHART,	"firstSliceAng", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-        GSF_XML_IN_NODE (DOUGHNUT, HOLE_SIZE, XL_NS_CHART,		"holeSize", GSF_XML_NO_CONTENT, NULL, NULL),
-
-      GSF_XML_IN_NODE (PLOTAREA, DATA_TABLE, XL_NS_CHART, "dTable", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (DATA_TABLE, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (DATA_TABLE, TEXT_PR, XL_NS_CHART,  "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-        GSF_XML_IN_NODE (DATA_TABLE, DT_SHOW_H_BORDER, XL_NS_CHART, "showHorzBorder", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (DATA_TABLE, DT_SHOW_V_BORDER, XL_NS_CHART, "showVertBorder", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (DATA_TABLE, DT_SHOW_KEYS, XL_NS_CHART, "showKeys", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (DATA_TABLE, DT_SHOW_OUTLINE, XL_NS_CHART, "showOutline", GSF_XML_NO_CONTENT, NULL, NULL),
-
-    GSF_XML_IN_NODE (CHART, TITLE, XL_NS_CHART, "title", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-
-    GSF_XML_IN_NODE (CHART, LEGEND, XL_NS_CHART, "legend", GSF_XML_NO_CONTENT, &xlsx_chart_legend, NULL),
-      GSF_XML_IN_NODE (LEGEND, SHAPE_PR, XL_NS_CHART, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-      GSF_XML_IN_NODE (LEGEND, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-      GSF_XML_IN_NODE (LEGEND, LAYOUT, XL_NS_CHART, "layout", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-      GSF_XML_IN_NODE (LEGEND, LEGEND_POS, XL_NS_CHART, "legendPos", GSF_XML_NO_CONTENT, NULL, NULL),
-    GSF_XML_IN_NODE (CHART, CHART_HIDDEN, XL_NS_CHART, "plotVisOnly", GSF_XML_NO_CONTENT, NULL, NULL),
-    GSF_XML_IN_NODE (CHART, CHART_BLANKS, XL_NS_CHART, "dispBlanksAs", GSF_XML_NO_CONTENT, NULL, NULL),
-    GSF_XML_IN_NODE (CHART, AUTO_TITLE_DEL, XL_NS_CHART, "autoTitleDeleted", GSF_XML_NO_CONTENT, NULL, NULL),
-
-  GSF_XML_IN_NODE (CHART_SPACE, STYLE, XL_NS_CHART, "style", GSF_XML_NO_CONTENT, NULL, NULL),
-  GSF_XML_IN_NODE (CHART_SPACE, PRINT_SETTINGS, XL_NS_CHART, "printSettings", GSF_XML_NO_CONTENT, NULL, NULL),
-    GSF_XML_IN_NODE (PRINT_SETTINGS, PAGE_SETUP, XL_NS_CHART, "pageSetup", GSF_XML_NO_CONTENT, NULL, NULL),
-    GSF_XML_IN_NODE (PRINT_SETTINGS, PAGE_MARGINS, XL_NS_CHART, "pageMargins", GSF_XML_NO_CONTENT, NULL, NULL),
-    GSF_XML_IN_NODE (PRINT_SETTINGS, HEADER_FOOTER, XL_NS_CHART, "headerFooter", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (HEADER_FOOTER, ODD_HEADER, XL_NS_CHART, "oddHeader", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (HEADER_FOOTER, ODD_FOOTER, XL_NS_CHART, "oddFooter", GSF_XML_NO_CONTENT, NULL, NULL),
-  GSF_XML_IN_NODE (CHART_SPACE, LANG, XL_NS_CHART, "lang", GSF_XML_NO_CONTENT, NULL, NULL),
-GSF_XML_IN_NODE_END
-};
-
-/***********************************************************************/
-
-static void
-cb_axis_set_position (GObject *axis, XLSXAxisInfo *info,
-		      XLSXReadState *state)
-{
-	if (info->deleted) {
-		GSList *l = gog_chart_get_axes (state->chart, gog_axis_get_atype (GOG_AXIS (axis))), *cur;
-		GogAxis *visible = NULL;
-
-		for (cur = l; cur; cur = cur->next) {
-			gboolean invisible;
-			g_object_get (cur->data, "invisible", &invisible, NULL);
-			if (!invisible) {
-				visible = GOG_AXIS (cur->data);
-				break;
-			}
-		}
-		if (visible) {
-			GSList *l1, *cur1;
-
-			l1 = g_slist_copy ((GSList *) gog_axis_contributors (GOG_AXIS (axis)));
-			for (cur1 = l1; cur1; cur1 = cur1->next) {
-				if (GOG_IS_PLOT (cur1->data))
-					gog_plot_set_axis (GOG_PLOT (cur1->data), visible);
-			}
-			g_slist_free (l1);
-			/* now reparent the children of the hidden axis */
-			l1 = gog_object_get_children (GOG_OBJECT (axis), NULL);
-			for (cur1 = l1; cur1; cur1 = cur1->next) {
-				GogObject *obj = GOG_OBJECT (cur1->data);
-				GogObjectRole const *role = obj->role;
-				gog_object_clear_parent (obj);
-				gog_object_set_parent (obj, GOG_OBJECT (visible), role, obj->id);
-			}
-			g_slist_free (l1);
-		}
-	} else {
-		XLSXAxisInfo *cross_info = g_hash_table_lookup (state->axis.by_id, info->cross_id);
-		GogObject *obj;
-		g_return_if_fail (cross_info != NULL);
-		obj = GOG_OBJECT (cross_info->axis);
-		if (go_finite (cross_info->cross_value)) {
-			GnmValue *value = value_new_float (cross_info->cross_value);
-			GnmExprTop const *texpr = gnm_expr_top_new_constant (value);
-			gog_dataset_set_dim (GOG_DATASET (obj), GOG_AXIS_ELEM_CROSS_POINT,
-				gnm_go_data_scalar_new_expr (state->sheet, texpr), NULL);
-		}
-		g_object_set (obj, "pos", info->cross, "cross-axis-id", gog_object_get_id (GOG_OBJECT (axis)), NULL);
-	}
-}
-
-static void
-xlsx_axis_cleanup (XLSXReadState *state)
-{
-	GSList *list, *ptr;
-
-	/* clean out axis that were auto created */
-	list = gog_object_get_children (GOG_OBJECT (state->chart), NULL);
-	for (ptr = list; ptr != NULL ; ptr = ptr->next)
-		if (GOG_IS_AXIS (ptr->data) &&
-		    NULL == g_hash_table_lookup (state->axis.by_obj, ptr->data)) {
-			if (gog_object_is_deletable (GOG_OBJECT (ptr->data))) {
-				gog_object_clear_parent	(GOG_OBJECT (ptr->data));
-				g_object_unref (G_OBJECT (ptr->data));
-			}
-		}
-	g_slist_free (list);
-
-	g_hash_table_foreach (state->axis.by_obj,
-		(GHFunc)cb_axis_set_position, state);
-	g_hash_table_destroy (state->axis.by_obj);
-	g_hash_table_destroy (state->axis.by_id);
-	state->axis.by_obj = state->axis.by_id = NULL;
-}
-
-static void
-xlsx_read_chart (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	xmlChar const *part_id = NULL;
-
-	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
-		if (gsf_xml_in_namecmp (xin, attrs[0], XL_NS_DOC_REL, "id"))
-			part_id = attrs[1];
-	if (NULL != part_id) {
-		/* leave it in 'state' for the frame to insert */
-		state->so = sheet_object_graph_new (NULL);
-
-		state->graph	 = sheet_object_graph_get_gog (state->so);
-		state->cur_obj   = gog_object_add_by_name (GOG_OBJECT (state->graph), "Chart", NULL);
-		state->chart	 = GOG_CHART (state->cur_obj);
-		state->cur_style = NULL;
-		state->obj_stack = NULL;
-		state->dim_type  = GOG_MS_DIM_LABELS;
-		state->axis.by_id  = g_hash_table_new_full (g_str_hash, g_str_equal,
-			NULL, (GDestroyNotify) xlsx_axis_info_free);
-		state->axis.by_obj = g_hash_table_new (g_direct_hash, g_direct_equal);
-		xlsx_parse_rel_by_id (xin, part_id, xlsx_chart_dtd, xlsx_ns);
-
-		if (NULL != state->obj_stack) {
-			g_warning ("left over content on chart object stack");
-			g_slist_free (state->obj_stack);
-			state->obj_stack = NULL;
-		}
-
-		xlsx_axis_cleanup (state);
-		if (NULL != state->cur_style) {
-			g_warning ("left over style");
-			g_object_unref (state->cur_style);
-			state->cur_style = NULL;
-		}
-		state->cur_obj   = NULL;
-		state->chart = NULL;
-		state->graph = NULL;
-	}
-}
-
-/**************************************************************************/
-#define CELL	0
-#define OFFSET	1
-#define FROM	0
-#define TO	4
-#define COL	0
-#define ROW	2
-
-static void
-xlsx_draw_anchor_start (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-
-	g_return_if_fail (state->so == NULL);
-
-	memset ((gpointer)state->drawing_pos, 0, sizeof (state->drawing_pos));
-	state->drawing_pos_flags = 0;
-}
-
-static void
-xlsx_drawing_twoCellAnchor_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-
-	if (NULL == state->so) {
-		xlsx_warning (xin,
-			_("Dropping missing object"));
-	} else {
-		if ((state->drawing_pos_flags & 0xFF) == 0xFF) {
-			SheetObjectAnchor anchor;
-			GnmRange r;
-
-			range_init (&r,
-				state->drawing_pos[COL | FROM],
-				state->drawing_pos[ROW | FROM],
-				state->drawing_pos[COL | TO],
-				state->drawing_pos[ROW | TO]);
-
-#warning implement absolute offsets
-				sheet_object_anchor_init (&anchor, &r, NULL, GOD_ANCHOR_DIR_DOWN_RIGHT);
-				sheet_object_set_anchor (state->so, &anchor);
-				sheet_object_set_sheet (state->so, state->sheet);
-		} else
-			xlsx_warning (xin,
-				_("Dropping object with incomplete anchor %2x"), state->drawing_pos_flags);
-
-		g_object_unref (state->so);
-		state->so = NULL;
-	}
-}
-
-static void
-xlsx_drawing_oneCellAnchor_end (GsfXMLIn *xin, GsfXMLBlob *blob)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-
-	state->drawing_pos[COL | TO] = state->drawing_pos[COL | FROM] + 5;
-	state->drawing_pos[ROW | TO] = state->drawing_pos[ROW | FROM] + 5;
-	state->drawing_pos_flags |= ((1 << (COL | TO)) | (1 << (ROW | TO)));
-	xlsx_drawing_twoCellAnchor_end (xin, blob);
-}
-
-static void
-xlsx_drawing_ext (GsfXMLIn *xin, xmlChar const **attrs)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
-		if (attr_int64 (xin, attrs, "cx", state->drawing_pos + (COL | TO | OFFSET)))
-			state->drawing_pos_flags |= (1 << (COL | TO | OFFSET));
-		else if (attr_int64 (xin, attrs, "cy", state->drawing_pos + (ROW | TO | OFFSET)))
-			state->drawing_pos_flags |= (1 << (ROW | TO | OFFSET));
-}
-
-static void
-xlsx_drawing_pos (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
-	XLSXReadState	*state = (XLSXReadState *)xin->user_state;
-	gint64 val;
-	char  *end;
-
-	errno = 0;
-	val = g_ascii_strtoll (xin->content->str, &end, 10);
-	if (errno == ERANGE || end == xin->content->str || *end != '\0')
-		return;
-
-	state->drawing_pos[xin->node->user_data.v_int] = val;
-	state->drawing_pos_flags |= 1 << xin->node->user_data.v_int;
-#if 0
-	fprintf (stderr, "%s %s %s = %" G_GINT64_FORMAT "\n",
-		 (xin->node->user_data.v_int & TO) ? "To" : "From",
-		 (xin->node->user_data.v_int & ROW) ? "Row" : "Col",
-		 (xin->node->user_data.v_int & OFFSET) ? "Offset" : "",
-		 val);
-#endif
-}
-
-static GsfXMLInNode const xlsx_drawing_dtd[] = {
-GSF_XML_IN_NODE_FULL (START, START, -1, NULL, GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
-GSF_XML_IN_NODE_FULL (START, DRAWING, XL_NS_SS_DRAW, "wsDr", GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
-
-  GSF_XML_IN_NODE (DRAWING, TWO_CELL, XL_NS_SS_DRAW, "twoCellAnchor", GSF_XML_NO_CONTENT,
-		   &xlsx_draw_anchor_start, &xlsx_drawing_twoCellAnchor_end),
-    GSF_XML_IN_NODE (TWO_CELL, ANCHOR_FROM, XL_NS_SS_DRAW, "from", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE_FULL (ANCHOR_FROM, ANCHOR_FROM_COL,	XL_NS_SS_DRAW, "col",	 GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, FROM | COL | CELL),
-      GSF_XML_IN_NODE_FULL (ANCHOR_FROM, ANCHOR_FROM_COL_OFF,	XL_NS_SS_DRAW, "colOff", GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, FROM | COL | OFFSET),
-      GSF_XML_IN_NODE_FULL (ANCHOR_FROM, ANCHOR_FROM_ROW,	XL_NS_SS_DRAW, "row",    GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, FROM | ROW | CELL),
-      GSF_XML_IN_NODE_FULL (ANCHOR_FROM, ANCHOR_FROM_ROW_OFF,	XL_NS_SS_DRAW, "rowOff", GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, FROM | ROW | OFFSET),
-    GSF_XML_IN_NODE (TWO_CELL, TWO_CELL_TO, XL_NS_SS_DRAW, "to", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE_FULL (TWO_CELL_TO, TWO_CELL_TO_COL,	XL_NS_SS_DRAW, "col",    GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, TO | COL | CELL),
-      GSF_XML_IN_NODE_FULL (TWO_CELL_TO, TWO_CELL_TO_COL_OFF,	XL_NS_SS_DRAW, "colOff", GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, TO | COL | OFFSET),
-      GSF_XML_IN_NODE_FULL (TWO_CELL_TO, TWO_CELL_TO_ROW,	XL_NS_SS_DRAW, "row",	 GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, TO | ROW | CELL),
-      GSF_XML_IN_NODE_FULL (TWO_CELL_TO, TWO_CELL_TO_ROW_OFF,	XL_NS_SS_DRAW, "rowOff", GSF_XML_CONTENT, FALSE, TRUE, NULL, &xlsx_drawing_pos, TO | ROW | OFFSET),
-#undef FROM
-#undef TO
-#undef COL
-#undef ROW
-#undef CELL
-#undef OFFSET
-    GSF_XML_IN_NODE (TWO_CELL, SHAPE, XL_NS_SS_DRAW, "sp", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (SHAPE, SHAPE_PR, XL_NS_SS_DRAW, "spPr", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (SHAPE_PR, SP_PR_XFRM, XL_NS_DRAW, "xfrm", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (SP_PR_XFRM, SP_XFRM_OFF, XL_NS_DRAW, "off", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (SP_PR_XFRM, SP_XFRM_EXT, XL_NS_DRAW, "ext", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (SHAPE_PR, SP_PR_PRST_GEOM, XL_NS_DRAW, "prstGeom", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (SP_PR_PRST_GEOM, AV_LST, XL_NS_DRAW, "avLst", GSF_XML_NO_CONTENT, NULL, NULL),
-	GSF_XML_IN_NODE (SHAPE_PR, FILL_NONE,	XL_NS_DRAW, "noFill", GSF_XML_NO_CONTENT, &xlsx_chart_no_fill, NULL),
-	GSF_XML_IN_NODE (SHAPE_PR, FILL_SOLID,	XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, &xlsx_chart_solid_fill, NULL),
-	  GSF_XML_IN_NODE (FILL_SOLID, COLOR_THEMED, XL_NS_DRAW, "schemeClr", GSF_XML_NO_CONTENT, &xlsx_draw_color_themed, &xlsx_draw_color_end),
-	    GSF_XML_IN_NODE (COLOR_THEMED, COLOR_LUM, XL_NS_DRAW, "lumMod", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (FILL_SOLID, COLOR_RGB,	 XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, &xlsx_draw_color_rgb, &xlsx_draw_color_end),
-	    GSF_XML_IN_NODE (COLOR_RGB, RGB_ALPHA,	   XL_NS_DRAW, "alpha", GSF_XML_NO_CONTENT, &xlsx_draw_color_alpha, NULL),
-	    GSF_XML_IN_NODE (COLOR_RGB, RGB_GAMMA,	   XL_NS_DRAW, "gamma", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (COLOR_RGB, RGB_INV_GAMMA, XL_NS_DRAW, "invGamma", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (COLOR_RGB, RGB_SHADE,	   XL_NS_DRAW, "shade", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (COLOR_RGB, RGB_TINT,	   XL_NS_DRAW, "tint", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (COLOR_RGB, LN_DASH,	   XL_NS_DRAW, "prstDash", GSF_XML_NO_CONTENT, &xlsx_draw_line_dash, NULL),
-
-	GSF_XML_IN_NODE (SHAPE_PR, FILL_BLIP,	XL_NS_DRAW, "blipFill", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_BLIP,	XL_NS_DRAW, "blip", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_SRC,	XL_NS_DRAW, "srcRect", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (FILL_BLIP, FILL_BLIP_TILE,	XL_NS_DRAW, "tile", GSF_XML_NO_CONTENT, NULL, NULL),
-
-	GSF_XML_IN_NODE (SHAPE_PR, FILL_GRAD,	XL_NS_DRAW, "gradFill", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (FILL_GRAD, GRAD_LIST,	XL_NS_DRAW, "gsLst", GSF_XML_NO_CONTENT, NULL, NULL),
-	   GSF_XML_IN_NODE (GRAD_LIST, GRAD_LIST_ITEM, XL_NS_DRAW, "gs", GSF_XML_NO_CONTENT, NULL, NULL),
-	     GSF_XML_IN_NODE (GRAD_LIST_ITEM, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-	  GSF_XML_IN_NODE (FILL_GRAD, GRAD_LINE,	XL_NS_DRAW, "lin", GSF_XML_NO_CONTENT, NULL, NULL),
-
-	GSF_XML_IN_NODE (SHAPE_PR, FILL_PATT,	XL_NS_DRAW, "pattFill", GSF_XML_NO_CONTENT, &xlsx_chart_solid_fill, NULL),
-	  GSF_XML_IN_NODE (FILL_PATT, FILL_PATT_BG,	XL_NS_DRAW, "bgClr", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (FILL_PATT_BG, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-	  GSF_XML_IN_NODE (FILL_PATT, FILL_PATT_FG,	XL_NS_DRAW, "fgClr", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (FILL_PATT_FG, COLOR_RGB, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-
-	GSF_XML_IN_NODE (SHAPE_PR, SHAPE_PR_LN, XL_NS_DRAW, "ln", GSF_XML_NO_CONTENT, xlsx_style_line_start, &xlsx_style_line_end),
-	  GSF_XML_IN_NODE (SHAPE_PR_LN, LN_NOFILL, XL_NS_DRAW, "noFill", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (SHAPE_PR_LN, LN_DASH, XL_NS_DRAW, "prstDash", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-	  GSF_XML_IN_NODE (SHAPE_PR_LN, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-	  GSF_XML_IN_NODE (SHAPE_PR_LN, FILL_PATT,	XL_NS_DRAW, "pattFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-	  GSF_XML_IN_NODE (SHAPE_PR_LN, LN_MITER,	XL_NS_DRAW, "miter", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (SHAPE_PR_LN, LN_ROUND,	XL_NS_DRAW, "round", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (SHAPE_PR_LN, LN_HEAD,	XL_NS_DRAW, "headEnd", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (SHAPE_PR_LN, LN_TAIL,	XL_NS_DRAW, "tailEnd", GSF_XML_NO_CONTENT, NULL, NULL),
-
-	GSF_XML_IN_NODE (SHAPE_PR, TEXT_PR, XL_NS_CHART, "txPr", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_BODY,	XL_NS_DRAW, "bodyPr", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_STYLE,	XL_NS_DRAW, "lstStyle", GSF_XML_NO_CONTENT, NULL, NULL),
-	  GSF_XML_IN_NODE (TEXT_PR, TEXT_PR_P,	XL_NS_DRAW, "p", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-	    GSF_XML_IN_NODE (TEXT_PR_P, TX_RICH_R, XL_NS_DRAW, "r", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (TX_RICH_R, TX_RICH_R_PR, XL_NS_DRAW, "rPr", GSF_XML_NO_CONTENT, NULL, NULL),
-		GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_CS, XL_NS_DRAW, "cs", GSF_XML_NO_CONTENT, NULL, NULL),
-		GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_EA, XL_NS_DRAW, "ea", GSF_XML_NO_CONTENT, NULL, NULL),
-		GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_LATIN, XL_NS_DRAW, "latin", GSF_XML_NO_CONTENT, NULL, NULL),
-		GSF_XML_IN_NODE (TX_RICH_R_PR, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-		GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_UFILLTX, XL_NS_DRAW, "uFillTx", GSF_XML_NO_CONTENT, NULL, NULL),
-		GSF_XML_IN_NODE (TX_RICH_R_PR, PR_P_PR_DEF_ULNTX, XL_NS_DRAW, "uLnTx", GSF_XML_NO_CONTENT, NULL, NULL),
-
-	      GSF_XML_IN_NODE (TX_RICH_R, TX_RICH_R_T, XL_NS_DRAW,  "t", GSF_XML_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (TEXT_PR_P, PR_P_PR,	XL_NS_DRAW, "pPr", GSF_XML_NO_CONTENT, NULL, NULL),
-	      GSF_XML_IN_NODE (PR_P_PR, PR_P_PR_DEF, XL_NS_DRAW, "defRPr", GSF_XML_NO_CONTENT, NULL, NULL),
-		GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_CS, XL_NS_DRAW, "cs", GSF_XML_NO_CONTENT, NULL, NULL),
-		GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_EA, XL_NS_DRAW, "ea", GSF_XML_NO_CONTENT, NULL, NULL),
-		GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_LATIN, XL_NS_DRAW, "latin", GSF_XML_NO_CONTENT, NULL, NULL),
-		GSF_XML_IN_NODE (PR_P_PR_DEF, FILL_SOLID, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-		GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_UFILLTX, XL_NS_DRAW, "uFillTx", GSF_XML_NO_CONTENT, NULL, NULL),
-		GSF_XML_IN_NODE (PR_P_PR_DEF, PR_P_PR_DEF_ULNTX, XL_NS_DRAW, "uLnTx", GSF_XML_NO_CONTENT, NULL, NULL),
-	    GSF_XML_IN_NODE (TEXT_PR_P, PR_P_PR_END,XL_NS_DRAW, "endParaRPr", GSF_XML_NO_CONTENT, NULL, NULL),
-
-      GSF_XML_IN_NODE (SHAPE, TX_BODY, XL_NS_SS_DRAW, "txBody", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (TX_BODY, LST_STYLE, XL_NS_DRAW, "lstStyle", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-        GSF_XML_IN_NODE (TX_BODY, TX_BODY_PR, XL_NS_DRAW, "bodyPr", GSF_XML_NO_CONTENT, NULL, NULL),
-	GSF_XML_IN_NODE (TX_BODY, TEXT_PR_P,	XL_NS_DRAW, "p", GSF_XML_NO_CONTENT, NULL, NULL),			/* 2nd Def */
-
-      GSF_XML_IN_NODE (SHAPE, NV_SP_PR, XL_NS_SS_DRAW, "nvSpPr", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (NV_SP_PR, C_NV_SP_PR, XL_NS_SS_DRAW, "cNvSpPr", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (C_NV_SP_PR, SP_LOCKS, XL_NS_DRAW, "spLocks", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (NV_SP_PR, C_NV_PR, XL_NS_SS_DRAW, "cNvPr", GSF_XML_NO_CONTENT, NULL, NULL),
-
-    GSF_XML_IN_NODE (TWO_CELL, GRAPHIC_FRAME, XL_NS_SS_DRAW, "graphicFrame", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (GRAPHIC_FRAME, GRAPHIC_PR, XL_NS_SS_DRAW, "nvGraphicFramePr", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (GRAPHIC_PR, CNVPR, XL_NS_SS_DRAW, "cNvPr", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (GRAPHIC_PR, GRAPHIC_PR_CHILD, XL_NS_SS_DRAW, "cNvGraphicFramePr", GSF_XML_NO_CONTENT, NULL, NULL),
-          GSF_XML_IN_NODE (GRAPHIC_PR_CHILD, GRAPHIC_LOCKS, XL_NS_DRAW, "graphicFrameLocks", GSF_XML_NO_CONTENT, NULL, NULL),
-      GSF_XML_IN_NODE (GRAPHIC_FRAME, GRAPHIC, XL_NS_DRAW, "graphic", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE_FULL (GRAPHIC, GRAPHIC_DATA, XL_NS_DRAW, "graphicData",
-			      GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
-          GSF_XML_IN_NODE (GRAPHIC_DATA, CHART, XL_NS_CHART, "chart", GSF_XML_NO_CONTENT, &xlsx_read_chart, NULL),
-          GSF_XML_IN_NODE (GRAPHIC_DATA, GRAPHIC_PR_CHILD, XL_NS_SS_DRAW, "cNvGraphicFramePr", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-      GSF_XML_IN_NODE (GRAPHIC_FRAME, TWO_CELL_XFRM, XL_NS_SS_DRAW, "xfrm", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (TWO_CELL_XFRM, XFRM_OFF, XL_NS_DRAW, "off", GSF_XML_NO_CONTENT, NULL, NULL),
-        GSF_XML_IN_NODE (TWO_CELL_XFRM, XFRM_EXT, XL_NS_DRAW, "ext", GSF_XML_NO_CONTENT, NULL, NULL),
-    GSF_XML_IN_NODE (TWO_CELL, CLIENT_DATA, XL_NS_SS_DRAW, "clientData", GSF_XML_NO_CONTENT, NULL, NULL),
-
-  GSF_XML_IN_NODE (DRAWING, ONE_CELL, XL_NS_SS_DRAW, "oneCellAnchor", GSF_XML_NO_CONTENT,
-		   &xlsx_draw_anchor_start, &xlsx_drawing_oneCellAnchor_end),
-    GSF_XML_IN_NODE (ONE_CELL, ANCHOR_FROM, XL_NS_SS_DRAW, "from", GSF_XML_NO_CONTENT, NULL, NULL),		/* 2nd Def */
-    GSF_XML_IN_NODE (ONE_CELL, ONE_CELL_EXT, XL_NS_SS_DRAW, "ext", GSF_XML_NO_CONTENT, &xlsx_drawing_ext, NULL),
-    GSF_XML_IN_NODE (ONE_CELL, CLIENT_DATA, XL_NS_SS_DRAW, "clientData", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-    GSF_XML_IN_NODE (ONE_CELL, GRAPHIC_FRAME, XL_NS_SS_DRAW, "graphicFrame", GSF_XML_NO_CONTENT, NULL, NULL),	/* 2nd Def */
-GSF_XML_IN_NODE_END
-};
+#include "xlsx-read-drawing.c"
 
 /***********************************************************************/
 
@@ -5437,6 +3886,7 @@ GSF_XML_IN_NODE_FULL (START, STYLE_INFO, XL_NS_SS, "styleSheet", GSF_XML_NO_CONT
       GSF_XML_IN_NODE (FILL, IMAGE_FILL, XL_NS_SS, "image", GSF_XML_NO_CONTENT, NULL, NULL),
       GSF_XML_IN_NODE (FILL, GRADIENT_FILL, XL_NS_SS, "gradientFill", GSF_XML_NO_CONTENT, &xlsx_CT_GradientFill, NULL),
 	GSF_XML_IN_NODE (GRADIENT_FILL, GRADIENT_STOPS, XL_NS_SS, "stop", GSF_XML_NO_CONTENT, NULL, NULL),
+	  GSF_XML_IN_NODE (GRADIENT_STOPS, GRADIENT_COLOR, XL_NS_SS, "color", GSF_XML_NO_CONTENT, NULL, NULL),
 
   GSF_XML_IN_NODE_FULL (STYLE_INFO, BORDERS, XL_NS_SS, "borders", GSF_XML_NO_CONTENT,
 			FALSE, FALSE, &xlsx_collection_begin, &xlsx_collection_end, XLSX_COLLECT_BORDERS),
@@ -5700,6 +4150,8 @@ xlsx_file_open (GOFileOpener const *fo, GOIOContext *context,
 	state.convs = xlsx_conventions_new ();
 	state.theme_colors_by_name = g_hash_table_new_full (g_str_hash, g_str_equal,
 		(GDestroyNotify)g_free, NULL);
+	/* fill in some default colors (when theme is absent */
+	g_hash_table_replace (state.theme_colors_by_name, g_strdup ("bg1"), GUINT_TO_POINTER (GO_COLOR_WHITE));
 	state.pivot.cache_by_id = g_hash_table_new_full (g_str_hash, g_str_equal,
 		(GDestroyNotify)g_free, (GDestroyNotify) g_object_unref);
 
diff --git a/plugins/excel/xlsx-write-drawing.c b/plugins/excel/xlsx-write-drawing.c
new file mode 100644
index 0000000..9989adb
--- /dev/null
+++ b/plugins/excel/xlsx-write-drawing.c
@@ -0,0 +1,541 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * xlsx-drawing-write.c : export MS Office Open xlsx drawings and charts.
+ *
+ * Copyright (C) 2006-2007 Jody Goldberg (jody gnome org)
+ * Copyright (C) 2011 Jean Brefort (jean brefort normalesup org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+ * USA
+ */
+
+/*****************************************************************************/
+
+static void
+xlsx_write_chart_cstr_unchecked (GsfXMLOut *xml, char const *name, char const *val)
+{
+	gsf_xml_out_start_element (xml, name);
+	gsf_xml_out_add_cstr_unchecked (xml, "val", val);
+	gsf_xml_out_end_element (xml);
+}
+static void
+xlsx_write_chart_bool (GsfXMLOut *xml, char const *name, gboolean val)
+{
+	gsf_xml_out_start_element (xml, name);
+	xlsx_add_bool (xml, "val", val);
+	gsf_xml_out_end_element (xml);
+}
+
+static void
+xlsx_write_chart_int (GsfXMLOut *xml, char const *name, int def_val, int val)
+{
+	gsf_xml_out_start_element (xml, name);
+	if (val != def_val)
+		gsf_xml_out_add_int (xml, "val", val);
+	gsf_xml_out_end_element (xml);
+}
+
+static void
+xlsx_write_chart_uint (GsfXMLOut *xml, char const *name, int def_val, int val)
+{
+	gsf_xml_out_start_element (xml, name);
+	if (val != def_val)
+		gsf_xml_out_add_uint (xml, "val", val);
+	gsf_xml_out_end_element (xml);
+}
+
+static void
+xlsx_write_chart_float (GsfXMLOut *xml, char const *name, double def_val, double val)
+{
+	gsf_xml_out_start_element (xml, name);
+	if (val != def_val)
+		gsf_xml_out_add_float (xml, "val", val, -1);
+	gsf_xml_out_end_element (xml);
+}
+
+static void
+xlsx_write_plot_1_5_type (GsfXMLOut *xml, GogObject const *plot)
+{
+	char const *type;
+	g_object_get (G_OBJECT (plot), "type", &type, NULL);
+	if (0 == strcmp (type, "as_percentage"))
+		type = "percentStacked";
+	else if (0 == strcmp (type, "stacked"))
+		type = "stacked";
+	else
+		type = "clustered";
+	xlsx_write_chart_cstr_unchecked (xml, "c:grouping", type);
+}
+
+static void
+xlsx_write_series_dim (XLSXWriteState *state, GsfXMLOut *xml, GogSeries const *series,
+		       char const *name, GogMSDimType ms_type)
+{
+	GogSeriesDesc const *desc = &gog_plot_description (gog_series_get_plot (series))->series;
+	unsigned dim;
+	GOData const *dat;
+
+	for (dim = 0; dim < desc->num_dim; dim++)
+		if (desc->dim[dim].ms_type == ms_type)
+			break;
+	if (dim == desc->num_dim)
+		return;
+	dat = gog_dataset_get_dim (GOG_DATASET (series), dim);
+	if (NULL != dat) {
+		GnmExprTop const *texpr = gnm_go_data_get_expr (dat);
+		if (NULL != texpr) {
+			GnmParsePos pp;
+			char *str = gnm_expr_top_as_string (texpr,
+				parse_pos_init (&pp, (Workbook *)state->base.wb, NULL, 0,0 ),
+				state->convs);
+			gsf_xml_out_start_element (xml, name);
+			gsf_xml_out_start_element (xml, "c:numRef");
+			gsf_xml_out_simple_element (xml, "c:f", str);
+			gsf_xml_out_end_element (xml);
+			gsf_xml_out_end_element (xml);
+
+			g_free (str);
+		}
+	}
+}
+
+static void
+xlsx_write_rgbarea (GsfXMLOut *xml, GOColor color)
+{
+	char *buf = g_strdup_printf ("%06x", (guint) color >> 8);
+	int alpha = GO_COLOR_UINT_A (color); 
+	gsf_xml_out_start_element (xml, "a:srgbClr");
+	gsf_xml_out_add_cstr_unchecked (xml, "val", buf);
+	g_free (buf);
+	if (alpha < 255) {
+		gsf_xml_out_start_element (xml, "a:alpha");
+		gsf_xml_out_add_int (xml, "val", alpha * 100000 / 255);
+		gsf_xml_out_end_element (xml);
+	}
+	gsf_xml_out_end_element (xml);
+}
+
+static void
+xlsx_write_go_style (GsfXMLOut *xml, GOStyle *style)
+{
+	gsf_xml_out_start_element (xml, "c:spPr");
+	if ((style->interesting_fields & (GO_STYLE_LINE | GO_STYLE_OUTLINE)) &&
+	    style->line.dash_type != GO_LINE_NONE) {/* TODO: add more tests for transparent line */
+		/* export the line color */
+		gsf_xml_out_start_element (xml, "a:ln");
+		if (style->line.width > 0)
+			gsf_xml_out_add_int (xml, "w", style->line.width * 12700); 
+		gsf_xml_out_start_element (xml, "a:solidFill");
+		xlsx_write_rgbarea (xml, style->line.color);
+		gsf_xml_out_end_element (xml);
+		
+		gsf_xml_out_end_element (xml);
+	}
+	if ((style->interesting_fields & GO_STYLE_FILL) &&
+	    style->fill.type != GO_STYLE_FILL_NONE) {/* TODO add tests for transparent backgrounds */
+		switch (style->fill.type) {
+		default :
+			g_warning ("invalid fill type, saving as none");
+		case GO_STYLE_FILL_IMAGE:
+			/* FIXME: export image */
+		case GO_STYLE_FILL_PATTERN:
+			switch (style->fill.pattern.pattern) {
+			case GO_PATTERN_SOLID:
+				gsf_xml_out_start_element (xml, "a:solidFill");
+				xlsx_write_rgbarea (xml, style->fill.pattern.back);
+				gsf_xml_out_end_element (xml);
+				break;
+			case GO_PATTERN_FOREGROUND_SOLID:
+				gsf_xml_out_start_element (xml, "a:solidFill");
+				xlsx_write_rgbarea (xml, style->fill.pattern.fore);
+				gsf_xml_out_end_element (xml);
+				break;
+			}
+			break;
+		case GO_STYLE_FILL_GRADIENT:
+			break;
+		}
+	}
+	gsf_xml_out_end_element (xml);
+	if (style->interesting_fields & GO_STYLE_MARKER) {
+	}
+}
+
+static void
+xlsx_write_chart (XLSXWriteState *state, GsfOutput *chart_part, SheetObject *so)
+{
+	GogGraph const	*graph;
+	GogObject const	*chart;
+	GogObject const *plot;
+	char const *plot_type;
+	GogObject const *obj;
+	GsfXMLOut *xml;
+	gboolean failed = FALSE;
+	gboolean use_xy = FALSE;
+	GogAxisType axis_type[3] = {GOG_AXIS_X, GOG_AXIS_Y, GOG_AXIS_UNKNOWN};
+	unsigned i;
+	double explosion = 0.;
+
+	graph = sheet_object_graph_get_gog (so);
+	if (NULL == graph)
+		return;
+	chart = gog_object_get_child_by_name (GOG_OBJECT (graph), "Chart");
+	if (NULL == chart)
+		return;
+	plot = gog_object_get_child_by_name (GOG_OBJECT (chart), "Plot");
+	if (NULL == plot)
+		return;
+	plot_type = G_OBJECT_TYPE_NAME (plot);
+	xml = gsf_xml_out_new (chart_part);
+	gsf_xml_out_start_element (xml, "c:chartSpace");
+	gsf_xml_out_add_cstr_unchecked (xml, "xmlns:c", ns_chart);
+	gsf_xml_out_add_cstr_unchecked (xml, "xmlns:a", ns_drawing);
+	gsf_xml_out_add_cstr_unchecked (xml, "xmlns:r", ns_rel);
+	xlsx_write_go_style (xml, go_styled_object_get_style (GO_STYLED_OBJECT (chart)));
+
+	gsf_xml_out_start_element (xml, "c:chart");
+	gsf_xml_out_start_element (xml, "c:plotArea");
+	/* save grid style here */
+	obj = gog_object_get_child_by_name (GOG_OBJECT (chart), "Backplane");
+	if (obj)
+		xlsx_write_go_style (xml, go_styled_object_get_style (GO_STYLED_OBJECT (obj)));
+	if (0 == strcmp (plot_type, "GogAreaPlot")) {
+		gsf_xml_out_start_element (xml, "c:areaChart");
+		xlsx_write_plot_1_5_type (xml, plot);
+	} else if (0 == strcmp (plot_type, "GogBarColPlot")) {
+		gboolean horizontal;
+		int overlap_percentage, gap_percentage;
+		g_object_get (G_OBJECT (plot),
+			"horizontal",		&horizontal,
+			"overlap-percentage",	&overlap_percentage,
+			"gap-percentage",	&gap_percentage,
+			NULL);
+		if (horizontal) {
+			axis_type[0] = GOG_AXIS_Y;
+			axis_type[1] = GOG_AXIS_X;
+		}
+		gsf_xml_out_start_element (xml, "c:barChart");
+		gsf_xml_out_simple_element (xml, "c:barDir",
+			horizontal ? "bar" : "col");
+		xlsx_write_plot_1_5_type (xml, plot);
+
+		gsf_xml_out_start_element (xml, "c:overlap");
+		gsf_xml_out_add_int (xml, "val", -overlap_percentage);
+		gsf_xml_out_end_element (xml); /* </c:grouping> */
+		
+		gsf_xml_out_start_element (xml, "c:gapWidth");
+		gsf_xml_out_add_int (xml, "val", gap_percentage);
+		gsf_xml_out_end_element (xml); /* </c:grouping> */
+	} else if (0 == strcmp (plot_type, "GogLinePlot")) {
+		gsf_xml_out_start_element (xml, "c:lineChart");
+		xlsx_write_plot_1_5_type (xml, plot);
+	} else if (0 == strcmp (plot_type, "GogPiePlot") ||
+		   0 == strcmp (plot_type, "GogRingPlot")) {
+		double initial_angle = 0., center_size = 0.;
+		gint16 center = 0;
+		if (0 == strcmp (plot_type, "GogRingPlot")) {
+			gsf_xml_out_start_element (xml, "c:doughnutChart");
+			g_object_get (G_OBJECT (plot), "center-size", &center_size, NULL);
+			center = (int)floor (center_size * 100. + .5);
+			xlsx_write_chart_int (xml, "c:holeSize", 10,
+				CLAMP (center, 10, 90));
+		} else
+			gsf_xml_out_start_element (xml, "c:pieChart");
+
+		g_object_get (G_OBJECT (plot),
+			"initial-angle",	 &initial_angle,
+			NULL);
+		xlsx_write_chart_int (xml, "c:firstSliceAng", 0, (int) initial_angle);
+#if 0
+		double default_separation = 0.;
+		/* handled in series ? */
+		"default-separation",	&default_separation,
+		xlsx_write_chart_int (xml, "c:explosion", 0, default_separation);
+#endif
+		axis_type[0] = axis_type[1] = GOG_AXIS_UNKNOWN;
+			   g_object_get (G_OBJECT (plot), "default-separation", &explosion, NULL);
+	} else if (0 == strcmp (plot_type, "GogRadarPlot") ||
+		   0 == strcmp (plot_type, "GogRadarAreaPlot")) {
+		gsf_xml_out_start_element (xml, "c:radarChart");
+	} else if (0 == strcmp (plot_type, "GogBubblePlot")) {
+		gboolean show_neg = FALSE, in_3d = FALSE, as_area = TRUE;
+		g_object_get (G_OBJECT (plot),
+			"show-negatives",	&show_neg,
+			"in-3d",		&in_3d,
+			"size-as-area",		&as_area,
+			NULL);
+		gsf_xml_out_start_element (xml, "c:bubbleChart");
+		xlsx_write_chart_bool (xml, "c:showNegBubbles", show_neg);
+		xlsx_write_chart_cstr_unchecked (xml, "c:sizeRepresents",
+			as_area ? "area" : "w");
+		if (in_3d)
+			xlsx_write_chart_bool (xml, "c:bubble3D", TRUE);
+		use_xy = TRUE;
+	} else if ( 0 == strcmp (plot_type, "GogXYPlot")) {
+		gboolean has_lines, has_markers, use_splines;
+		char const *style;
+		g_object_get (G_OBJECT (plot),
+		              "default-style-has-lines", &has_lines,
+		              "default-style-has-markers", &has_markers,
+		              "use-splines", &use_splines,
+		              NULL);
+		style = (has_lines)?
+				(use_splines?
+					(has_markers? "smoothMarker": "smooth"):
+					(has_markers? "lineMarker": "line")):
+				(has_markers? "markers": "none"); 
+		use_xy = TRUE;
+		gsf_xml_out_start_element (xml, "c:scatterChart");
+		xlsx_write_chart_cstr_unchecked (xml, "c:scatterStyle", style);
+	} else if (0 == strcmp (plot_type, "GogContourPlot") ||
+		   0 == strcmp (plot_type, "XLContourPlot")) {
+		gsf_xml_out_start_element (xml, "c:surfaceChart");
+	} else {
+		g_warning ("unexpected plot type %s", plot_type);
+		failed = TRUE;
+		axis_type[0] = axis_type[1] = GOG_AXIS_UNKNOWN;
+	}
+	if (!failed) {
+		gboolean vary_by_element;
+		GSList const *series = gog_plot_get_series (GOG_PLOT (plot));
+		unsigned count = 0;
+		g_object_get (G_OBJECT (plot),
+			      "vary-style-by-element", &vary_by_element,
+			      NULL);
+		if (vary_by_element)
+			xlsx_write_chart_bool (xml, "c:varyColors", vary_by_element);
+		for ( ; NULL != series ; series = series->next) {
+			gsf_xml_out_start_element (xml, "c:ser");
+
+			xlsx_write_chart_int (xml, "c:idx", -1, count);
+			xlsx_write_chart_int (xml, "c:order", -1, count);
+			if (!vary_by_element) /* FIXME: we might loose some style elements */
+				xlsx_write_go_style (xml, go_styled_object_get_style (GO_STYLED_OBJECT (series->data)));
+			if (use_xy) {
+				xlsx_write_series_dim (state, xml, series->data,
+					"c:yVal", GOG_MS_DIM_VALUES);
+				xlsx_write_series_dim (state, xml, series->data,
+					"c:xVal",  GOG_MS_DIM_CATEGORIES);
+				xlsx_write_series_dim (state, xml, series->data,
+					"c:bubbleSize", GOG_MS_DIM_BUBBLES);
+			} else {
+				xlsx_write_series_dim (state, xml, series->data,
+					"c:val", GOG_MS_DIM_VALUES);
+				xlsx_write_series_dim (state, xml, series->data,
+					"c:cat",  GOG_MS_DIM_CATEGORIES);
+			}
+			if (explosion > 0.)
+				xlsx_write_chart_uint (xml, "c:explosion", 0, (unsigned) (explosion * 100));
+			gsf_xml_out_end_element (xml); /* </c:ser> */
+		}
+		/* write axes Ids */
+		for (i = 0; i < 3; i++)
+			if (axis_type[i] != GOG_AXIS_UNKNOWN)
+				xlsx_write_chart_uint (xml, "c:axId", 0, GPOINTER_TO_UINT (gog_plot_get_axis (GOG_PLOT (plot), axis_type[i])));
+		gsf_xml_out_end_element (xml);
+	}
+	/* Write axes */
+	/* first category axis */
+	/* FIXME: might be a date axis? */
+	for (i = 0; i < 3; i++)
+		if (axis_type[i] != GOG_AXIS_UNKNOWN) {
+			GSList *axes = gog_chart_get_axes (GOG_CHART (chart), axis_type[i]), *ptr;
+			for (ptr = axes; ptr; ptr = ptr->next) {
+				GogAxis *crossed = gog_axis_base_get_crossed_axis (GOG_AXIS_BASE (ptr->data));
+				GogAxisPosition pos;
+				GogGridLine *grid;
+				if (gog_axis_is_discrete (ptr->data))
+					gsf_xml_out_start_element (xml, "c:catAx");
+				else
+					gsf_xml_out_start_element (xml, "c:valAx");
+				xlsx_write_chart_int (xml, "c:axId", 0, GPOINTER_TO_UINT (ptr->data));
+				gsf_xml_out_start_element (xml, "c:scaling");
+				xlsx_write_chart_cstr_unchecked (xml, "c:orientation", gog_axis_is_inverted (GOG_AXIS (ptr->data))? "maxMin": "minMax");
+				// TODO: export min, max, an others
+				gsf_xml_out_end_element (xml);
+				xlsx_write_go_style (xml, go_styled_object_get_style (GO_STYLED_OBJECT (ptr->data)));
+				/* FIXME position might be "t" or "r" */
+				xlsx_write_chart_cstr_unchecked (xml, "c:axPos", (axis_type[i] == GOG_AXIS_X)? "b": "l");
+				xlsx_write_chart_int (xml, "c:crossAx", 0, GPOINTER_TO_UINT (crossed));
+				g_object_get (G_OBJECT (ptr->data), "pos", &pos, NULL);
+				switch (pos) {
+				default:
+				case GOG_AXIS_AT_LOW:
+					/* FIXME: might be wrong if the axis is inverted */
+					xlsx_write_chart_cstr_unchecked (xml, "c:crosses", "min");
+					break;
+				case GOG_AXIS_CROSS: {
+					double cross = gog_axis_base_get_cross_location (GOG_AXIS_BASE (ptr->data));
+					if (cross == 0.)
+						xlsx_write_chart_cstr_unchecked (xml, "c:crosses", "autoZero");
+					else
+						xlsx_write_chart_float (xml, "c:crossesAt", 0., cross);
+					break;
+				}
+				case GOG_AXIS_AT_HIGH:
+					xlsx_write_chart_cstr_unchecked (xml, "c:crosses", "max");
+					break;
+				}
+				/* grids */
+				grid = gog_axis_get_grid_line (GOG_AXIS (ptr->data), TRUE);
+				if (grid) {
+					gsf_xml_out_start_element (xml, "c:majorGridlines");
+					xlsx_write_go_style (xml, go_styled_object_get_style (GO_STYLED_OBJECT (grid)));
+					gsf_xml_out_end_element (xml);
+				}
+				grid = gog_axis_get_grid_line (GOG_AXIS (ptr->data), FALSE);
+				if (grid) {
+					gsf_xml_out_start_element (xml, "c:minorGridlines");
+					xlsx_write_go_style (xml, go_styled_object_get_style (GO_STYLED_OBJECT (grid)));
+					gsf_xml_out_end_element (xml);
+				}
+
+				/* finished with axis */
+				gsf_xml_out_end_element (xml);
+			}
+		}
+
+	gsf_xml_out_end_element (xml); /* </c:plotArea> */
+
+	if ((obj = gog_object_get_child_by_name (chart, "Legend"))) {
+		gsf_xml_out_start_element (xml, "c:legend");
+		gsf_xml_out_end_element (xml); /* </c:legend> */
+	}
+	gsf_xml_out_end_element (xml); /* </c:chart> */
+
+	gsf_xml_out_end_element (xml); /* </c:chartSpace> */
+	g_object_unref (xml);
+}
+
+static void
+xlsx_write_object_anchor (GsfXMLOut *xml, GnmCellPos const *pos, char const *element)
+{
+	gsf_xml_out_start_element (xml, element);
+	gsf_xml_out_simple_int_element (xml, "xdr:col", pos->col);
+	gsf_xml_out_simple_int_element (xml, "xdr:colOff", 0);
+	gsf_xml_out_simple_int_element (xml, "xdr:row", pos->row);
+	gsf_xml_out_simple_int_element (xml, "xdr:rowOff", 0);
+	gsf_xml_out_end_element (xml);
+}
+
+static char const *
+xlsx_write_objects (XLSXWriteState *state, GsfOutput *sheet_part, GSList *objects)
+{
+	GSList *obj, *chart_id, *chart_ids = NULL;
+	char *name, *tmp;
+	char const *rId, *rId1;
+	int count = 1;
+	GsfOutput *drawing_part, *chart_part;
+	GsfXMLOut *xml;
+	SheetObjectAnchor const *anchor;
+
+	if (NULL == state->drawing.dir)
+		state->drawing.dir = (GsfOutfile *)gsf_outfile_new_child (state->xl_dir, "drawings", TRUE);
+	if (NULL == state->chart.dir)
+		state->chart.dir = (GsfOutfile *)gsf_outfile_new_child (state->xl_dir, "charts", TRUE);
+
+	name = g_strdup_printf ("drawing%u.xml", ++state->drawing.count);
+	drawing_part = gsf_outfile_new_child_full (state->drawing.dir, name, FALSE,
+		"content-type", "application/vnd.openxmlformats-officedocument.drawing+xml",
+		NULL);
+	g_free (name);
+
+	rId = gsf_outfile_open_pkg_relate (GSF_OUTFILE_OPEN_PKG (drawing_part),
+		GSF_OUTFILE_OPEN_PKG (sheet_part), ns_rel_draw);
+
+	objects = sheet_objects_get (state->sheet, NULL, SHEET_OBJECT_GRAPH_TYPE);
+	for (obj = objects ; obj != NULL ; obj = obj->next) {
+		char *name = g_strdup_printf ("chart%u.xml", ++state->chart.count);
+		chart_part = gsf_outfile_new_child_full (state->chart.dir, name, FALSE,
+			"content-type", "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
+			NULL);
+		g_free (name);
+		rId1 = gsf_outfile_open_pkg_relate (GSF_OUTFILE_OPEN_PKG (chart_part),
+			GSF_OUTFILE_OPEN_PKG (drawing_part), ns_rel_chart);
+
+		chart_ids = g_slist_prepend (chart_ids, (gpointer)rId1);
+
+		xlsx_write_chart (state, chart_part, obj->data);
+		gsf_output_close (chart_part);
+		g_object_unref (chart_part);
+	}
+
+	xml = gsf_xml_out_new (drawing_part);
+	gsf_xml_out_start_element (xml, "xdr:wsDr");
+	gsf_xml_out_add_cstr_unchecked (xml, "xmlns:xdr", ns_ss_drawing);
+	gsf_xml_out_add_cstr_unchecked (xml, "xmlns:a", ns_drawing);
+
+	chart_id = g_slist_reverse (chart_ids);
+	for (obj = objects; obj != NULL ; obj = obj->next, chart_id = chart_id->next) {
+		anchor = sheet_object_get_anchor (obj->data);
+
+		gsf_xml_out_start_element (xml, "xdr:twoCellAnchor");
+		xlsx_write_object_anchor (xml, &anchor->cell_bound.start, "xdr:from");
+		xlsx_write_object_anchor (xml, &anchor->cell_bound.end, "xdr:to");
+
+		gsf_xml_out_start_element (xml, "xdr:graphicFrame");
+		gsf_xml_out_add_cstr_unchecked (xml, "macro", "");
+
+		gsf_xml_out_start_element (xml, "xdr:nvGraphicFramePr");
+
+		gsf_xml_out_start_element (xml, "xdr:cNvPr");
+		gsf_xml_out_add_int (xml, "id",  count+1);
+		gsf_xml_out_add_cstr_unchecked (xml, "name",
+			(tmp = g_strdup_printf ("Chart %d", count)));
+		g_free (tmp);
+		count++;
+		gsf_xml_out_end_element (xml);
+
+		gsf_xml_out_simple_element (xml, "xdr:cNvGraphicFramePr", NULL);
+		gsf_xml_out_end_element (xml); /* </xdr:nvGraphicFramePr> */
+
+		gsf_xml_out_start_element (xml, "xdr:xfrm");
+
+		gsf_xml_out_start_element (xml, "a:off");
+		gsf_xml_out_add_int (xml, "x", 0);
+		gsf_xml_out_add_int (xml, "y", 0);
+		gsf_xml_out_end_element (xml); /* </a:off> */
+
+		gsf_xml_out_start_element (xml, "a:ext");
+		gsf_xml_out_add_int (xml, "cx", 0);
+		gsf_xml_out_add_int (xml, "cy", 0);
+		gsf_xml_out_end_element (xml); /* </a:ext> */
+
+		gsf_xml_out_end_element (xml); /* </xdr:xfrm> */
+
+		gsf_xml_out_start_element (xml, "a:graphic");
+		gsf_xml_out_start_element (xml, "a:graphicData");
+		gsf_xml_out_add_cstr_unchecked (xml, "uri", ns_chart);
+		gsf_xml_out_start_element (xml, "c:chart");
+		gsf_xml_out_add_cstr_unchecked (xml, "xmlns:c", ns_chart);
+		gsf_xml_out_add_cstr_unchecked (xml, "xmlns:r", ns_rel);
+
+		gsf_xml_out_add_cstr_unchecked (xml, "r:id", chart_id->data);
+		gsf_xml_out_end_element (xml); /* </c:chart> */
+		gsf_xml_out_end_element (xml); /* </a:graphicData> */
+		gsf_xml_out_end_element (xml); /* </a:graphic> */
+		gsf_xml_out_end_element (xml); /* </xdr:graphicFrame> */
+		gsf_xml_out_simple_element (xml, "xdr:clientData", NULL);
+		gsf_xml_out_end_element (xml); /* </xdr:twoCellAnchor> */
+	}
+	g_slist_free (objects);
+	g_slist_free (chart_ids);
+
+	gsf_xml_out_end_element (xml); /* </wsDr> */
+	g_object_unref (xml);
+	gsf_output_close (drawing_part);
+	g_object_unref (drawing_part);
+
+	return rId;
+}
diff --git a/plugins/excel/xlsx-write.c b/plugins/excel/xlsx-write.c
index d0577e1..8e04c05 100644
--- a/plugins/excel/xlsx-write.c
+++ b/plugins/excel/xlsx-write.c
@@ -917,413 +917,6 @@ xlsx_write_print_info (XLSXWriteState *state, GsfXMLOut *xml)
 /**********************************************************************/
 
 static void
-xlsx_write_chart_cstr_unchecked (GsfXMLOut *xml, char const *name, char const *val)
-{
-	gsf_xml_out_start_element (xml, name);
-	gsf_xml_out_add_cstr_unchecked (xml, "val", val);
-	gsf_xml_out_end_element (xml);
-}
-static void
-xlsx_write_chart_bool (GsfXMLOut *xml, char const *name, gboolean val)
-{
-	gsf_xml_out_start_element (xml, name);
-	xlsx_add_bool (xml, "val", val);
-	gsf_xml_out_end_element (xml);
-}
-static void
-xlsx_write_chart_int (GsfXMLOut *xml, char const *name, int def_val, int val)
-{
-	gsf_xml_out_start_element (xml, name);
-	if (val != def_val)
-		gsf_xml_out_add_int (xml, "val", val);
-	gsf_xml_out_end_element (xml);
-}
-
-static void
-xlsx_write_plot_1_5_type (GsfXMLOut *xml, GogObject const *plot)
-{
-	char const *type;
-	g_object_get (G_OBJECT (plot), "type", &type, NULL);
-	if (0 == strcmp (type, "as_percentage"))
-		type = "percentStacked";
-	else if (0 == strcmp (type, "stacked"))
-		type = "stacked";
-	else
-		type = "clustered";
-	xlsx_write_chart_cstr_unchecked (xml, "c:grouping", type);
-}
-
-static void
-xlsx_write_series_dim (XLSXWriteState *state, GsfXMLOut *xml, GogSeries const *series,
-		       char const *name, GogMSDimType ms_type)
-{
-	GogSeriesDesc const *desc = &gog_plot_description (gog_series_get_plot (series))->series;
-	unsigned dim;
-	GOData const *dat;
-
-	for (dim = 0; dim < desc->num_dim; dim++)
-		if (desc->dim[dim].ms_type == ms_type)
-			break;
-	if (dim == desc->num_dim)
-		return;
-	dat = gog_dataset_get_dim (GOG_DATASET (series), dim);
-	if (NULL != dat) {
-		GnmExprTop const *texpr = gnm_go_data_get_expr (dat);
-		if (NULL != texpr) {
-			GnmParsePos pp;
-			char *str = gnm_expr_top_as_string (texpr,
-				parse_pos_init (&pp, (Workbook *)state->base.wb, NULL, 0,0 ),
-				state->convs);
-			gsf_xml_out_start_element (xml, name);
-			gsf_xml_out_start_element (xml, "c:numRef");
-			gsf_xml_out_simple_element (xml, "c:f", str);
-			gsf_xml_out_end_element (xml);
-			gsf_xml_out_end_element (xml);
-
-			g_free (str);
-		}
-	}
-}
-
-static void
-xlsx_write_rgbarea (GsfXMLOut *xml, GOColor color)
-{
-	char *buf = g_strdup_printf ("%06x", (guint) color >> 8);
-	int alpha = GO_COLOR_UINT_A (color); 
-	gsf_xml_out_start_element (xml, "a:srgbClr");
-	gsf_xml_out_add_cstr_unchecked (xml, "val", buf);
-	g_free (buf);
-	if (alpha < 255) {
-		gsf_xml_out_start_element (xml, "a:alpha");
-		gsf_xml_out_add_int (xml, "val", alpha * 100000 / 255);
-		gsf_xml_out_end_element (xml);
-	}
-	gsf_xml_out_end_element (xml);
-}
-
-static void
-xlsx_write_go_style (GsfXMLOut *xml, GOStyle *style)
-{
-	if (style->interesting_fields & (GO_STYLE_LINE | GO_STYLE_OUTLINE)) {
-		gsf_xml_out_start_element (xml, "c:spPr");
-		switch (style->fill.type) {
-		default :
-			g_warning ("invalid fill type, saving as none");
-		case GO_STYLE_FILL_IMAGE:
-			/* FIXME: export image */
-		case GO_STYLE_FILL_NONE:
-			/* hmm, how should we do that? */
-			break;
-		case GO_STYLE_FILL_PATTERN:
-			switch (style->fill.pattern.pattern) {
-			case GO_PATTERN_SOLID:
-				gsf_xml_out_start_element (xml, "a:solidFill");
-				xlsx_write_rgbarea (xml, style->fill.pattern.back);
-				gsf_xml_out_end_element (xml);
-				break;
-			case GO_PATTERN_FOREGROUND_SOLID:
-				gsf_xml_out_start_element (xml, "a:solidFill");
-				xlsx_write_rgbarea (xml, style->fill.pattern.fore);
-				gsf_xml_out_end_element (xml);
-				break;
-			}
-			break;
-		case GO_STYLE_FILL_GRADIENT:
-			break;
-		}
-		gsf_xml_out_end_element (xml);
-	}
-	if (style->interesting_fields & GO_STYLE_FILL) {
-	}
-	if (style->interesting_fields & GO_STYLE_MARKER) {
-	}
-}
-
-static void
-xlsx_write_chart (XLSXWriteState *state, GsfOutput *chart_part, SheetObject *so)
-{
-	GogGraph const	*graph;
-	GogObject const	*chart;
-	GogObject const *plot;
-	char const *plot_type;
-	GogObject const *obj;
-	GsfXMLOut *xml;
-	gboolean failed = FALSE;
-	gboolean use_xy = FALSE;
-
-	graph = sheet_object_graph_get_gog (so);
-	if (NULL == graph)
-		return;
-	chart = gog_object_get_child_by_name (GOG_OBJECT (graph), "Chart");
-	if (NULL == chart)
-		return;
-	plot = gog_object_get_child_by_name (GOG_OBJECT (chart), "Plot");
-	if (NULL == plot)
-		return;
-	plot_type = G_OBJECT_TYPE_NAME (plot);
-	xml = gsf_xml_out_new (chart_part);
-	gsf_xml_out_start_element (xml, "c:chartSpace");
-	gsf_xml_out_add_cstr_unchecked (xml, "xmlns:c", ns_chart);
-	gsf_xml_out_add_cstr_unchecked (xml, "xmlns:a", ns_drawing);
-	gsf_xml_out_add_cstr_unchecked (xml, "xmlns:r", ns_rel);
-	xlsx_write_go_style (xml, go_styled_object_get_style (GO_STYLED_OBJECT (chart)));
-
-	gsf_xml_out_start_element (xml, "c:chart");
-	gsf_xml_out_start_element (xml, "c:plotArea");
-	/* save grid style here */
-	if (0 == strcmp (plot_type, "GogAreaPlot")) {
-		gsf_xml_out_start_element (xml, "c:areaChart");
-		xlsx_write_plot_1_5_type (xml, plot);
-	} else if (0 == strcmp (plot_type, "GogBarColPlot")) {
-		gboolean horizontal;
-		int overlap_percentage, gap_percentage;
-		g_object_get (G_OBJECT (plot),
-			"horizontal",		&horizontal,
-			"overlap-percentage",	&overlap_percentage,
-			"gap-percentage",	&gap_percentage,
-			NULL);
-		gsf_xml_out_start_element (xml, "c:barChart");
-		gsf_xml_out_simple_element (xml, "c:barDir",
-			horizontal ? "bar" : "col");
-		xlsx_write_plot_1_5_type (xml, plot);
-
-		gsf_xml_out_start_element (xml, "c:overlap");
-		gsf_xml_out_add_int (xml, "val", -overlap_percentage);
-		gsf_xml_out_end_element (xml); /* </c:grouping> */
-		
-		gsf_xml_out_start_element (xml, "c:gapWidth");
-		gsf_xml_out_add_int (xml, "val", gap_percentage);
-		gsf_xml_out_end_element (xml); /* </c:grouping> */
-	} else if (0 == strcmp (plot_type, "GogLinePlot")) {
-		gsf_xml_out_start_element (xml, "c:lineChart");
-		xlsx_write_plot_1_5_type (xml, plot);
-	} else if (0 == strcmp (plot_type, "GogPiePlot") ||
-		   0 == strcmp (plot_type, "GogRingPlot")) {
-		double initial_angle = 0., center_size = 0.;
-		gboolean vary;
-		gint16 center = 0;
-		if (0 == strcmp (plot_type, "GogRingPlot")) {
-			gsf_xml_out_start_element (xml, "c:doughnutChart");
-			g_object_get (G_OBJECT (plot), "center-size", &center_size, NULL);
-			center = (int)floor (center_size * 100. + .5);
-			xlsx_write_chart_int (xml, "c:holeSize", 10,
-				CLAMP (center, 10, 90));
-		} else
-			gsf_xml_out_start_element (xml, "c:pieChart");
-
-		g_object_get (G_OBJECT (plot),
-			"vary-style-by-element", &vary,
-			"initial-angle",	 &initial_angle,
-			NULL);
-		xlsx_write_chart_bool (xml, "c:varyColors", vary);
-		xlsx_write_chart_int (xml, "c:firstSliceAng", 0, (int) initial_angle);
-#if 0
-		double default_separation = 0.;
-		/* handled in series ? */
-		"default-separation",	&default_separation,
-		xlsx_write_chart_int (xml, "c:explosion", 0, default_separation);
-#endif
-	} else if (0 == strcmp (plot_type, "GogRadarPlot") ||
-		   0 == strcmp (plot_type, "GogRadarAreaPlot")) {
-		gsf_xml_out_start_element (xml, "c:radarChart");
-	} else if (0 == strcmp (plot_type, "GogBubblePlot")) {
-		gboolean show_neg = FALSE, in_3d = FALSE, as_area = TRUE;
-		g_object_get (G_OBJECT (plot),
-			"show-negatives",	&show_neg,
-			"in-3d",		&in_3d,
-			"size-as-area",		&as_area,
-			NULL);
-		gsf_xml_out_start_element (xml, "c:bubbleChart");
-		xlsx_write_chart_bool (xml, "c:showNegBubbles", show_neg);
-		xlsx_write_chart_cstr_unchecked (xml, "c:sizeRepresents",
-			as_area ? "area" : "w");
-		if (in_3d)
-			xlsx_write_chart_bool (xml, "c:bubble3D", TRUE);
-		use_xy = TRUE;
-	} else if ( 0 == strcmp (plot_type, "GogXYPlot")) {
-		gboolean has_lines, has_markers, use_splines;
-		char const *style;
-		g_object_get (G_OBJECT (plot),
-		              "default-style-has-lines", &has_lines,
-		              "default-style-has-markers", &has_markers,
-		              "use-splines", &use_splines,
-		              NULL);
-		style = (has_lines)?
-				(use_splines?
-					(has_markers? "smoothMarker": "smooth"):
-					(has_markers? "lineMarker": "line")):
-				(has_markers? "markers": "none"); 
-		use_xy = TRUE;
-		gsf_xml_out_start_element (xml, "c:scatterChart");
-		xlsx_write_chart_cstr_unchecked (xml, "c:scatterStyle", style);
-	} else if (0 == strcmp (plot_type, "GogContourPlot") ||
-		   0 == strcmp (plot_type, "XLContourPlot")) {
-		gsf_xml_out_start_element (xml, "c:surfaceChart");
-	} else {
-		g_warning ("unexpected plot type %s", plot_type);
-		failed = TRUE;
-	}
-	if (!failed) {
-		GSList const *series = gog_plot_get_series (GOG_PLOT (plot));
-		unsigned count = 0;
-		for ( ; NULL != series ; series = series->next) {
-			gsf_xml_out_start_element (xml, "c:ser");
-
-			xlsx_write_chart_int (xml, "c:idx", -1, count);
-			xlsx_write_chart_int (xml, "c:order", -1, count);
-			if (use_xy) {
-				xlsx_write_series_dim (state, xml, series->data,
-					"c:yVal", GOG_MS_DIM_VALUES);
-				xlsx_write_series_dim (state, xml, series->data,
-					"c:xVal",  GOG_MS_DIM_CATEGORIES);
-				xlsx_write_series_dim (state, xml, series->data,
-					"c:bubbleSize", GOG_MS_DIM_BUBBLES);
-			} else {
-				xlsx_write_series_dim (state, xml, series->data,
-					"c:val", GOG_MS_DIM_VALUES);
-				xlsx_write_series_dim (state, xml, series->data,
-					"c:cat",  GOG_MS_DIM_CATEGORIES);
-			}
-			gsf_xml_out_end_element (xml); /* </c:ser> */
-		}
-		gsf_xml_out_end_element (xml);
-	}
-
-	gsf_xml_out_end_element (xml); /* </c:plotArea> */
-
-	if ((obj = gog_object_get_child_by_name (chart, "Legend"))) {
-		gsf_xml_out_start_element (xml, "c:legend");
-		gsf_xml_out_end_element (xml); /* </c:legend> */
-	}
-	gsf_xml_out_end_element (xml); /* </c:chart> */
-
-	gsf_xml_out_end_element (xml); /* </c:chartSpace> */
-	g_object_unref (xml);
-}
-
-static void
-xlsx_write_object_anchor (GsfXMLOut *xml, GnmCellPos const *pos, char const *element)
-{
-	gsf_xml_out_start_element (xml, element);
-	gsf_xml_out_simple_int_element (xml, "xdr:col", pos->col);
-	gsf_xml_out_simple_int_element (xml, "xdr:colOff", 0);
-	gsf_xml_out_simple_int_element (xml, "xdr:row", pos->row);
-	gsf_xml_out_simple_int_element (xml, "xdr:rowOff", 0);
-	gsf_xml_out_end_element (xml);
-}
-
-static char const *
-xlsx_write_objects (XLSXWriteState *state, GsfOutput *sheet_part, GSList *objects)
-{
-	GSList *obj, *chart_id, *chart_ids = NULL;
-	char *name, *tmp;
-	char const *rId, *rId1;
-	int count = 1;
-	GsfOutput *drawing_part, *chart_part;
-	GsfXMLOut *xml;
-	SheetObjectAnchor const *anchor;
-
-	if (NULL == state->drawing.dir)
-		state->drawing.dir = (GsfOutfile *)gsf_outfile_new_child (state->xl_dir, "drawings", TRUE);
-	if (NULL == state->chart.dir)
-		state->chart.dir = (GsfOutfile *)gsf_outfile_new_child (state->xl_dir, "charts", TRUE);
-
-	name = g_strdup_printf ("drawing%u.xml", ++state->drawing.count);
-	drawing_part = gsf_outfile_new_child_full (state->drawing.dir, name, FALSE,
-		"content-type", "application/vnd.openxmlformats-officedocument.drawing+xml",
-		NULL);
-	g_free (name);
-
-	rId = gsf_outfile_open_pkg_relate (GSF_OUTFILE_OPEN_PKG (drawing_part),
-		GSF_OUTFILE_OPEN_PKG (sheet_part), ns_rel_draw);
-
-	obj = objects = g_slist_reverse (objects);
-	for (obj = objects ; obj != NULL ; obj = obj->next) {
-		char *name = g_strdup_printf ("chart%u.xml", ++state->chart.count);
-		chart_part = gsf_outfile_new_child_full (state->chart.dir, name, FALSE,
-			"content-type", "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
-			NULL);
-		g_free (name);
-		rId1 = gsf_outfile_open_pkg_relate (GSF_OUTFILE_OPEN_PKG (chart_part),
-			GSF_OUTFILE_OPEN_PKG (drawing_part), ns_rel_chart);
-
-		chart_ids = g_slist_prepend (chart_ids, (gpointer)rId1);
-
-		xlsx_write_chart (state, chart_part, obj->data);
-		gsf_output_close (chart_part);
-		g_object_unref (chart_part);
-	}
-
-	xml = gsf_xml_out_new (drawing_part);
-	gsf_xml_out_start_element (xml, "xdr:wsDr");
-	gsf_xml_out_add_cstr_unchecked (xml, "xmlns:xdr", ns_ss_drawing);
-	gsf_xml_out_add_cstr_unchecked (xml, "xmlns:a", ns_drawing);
-
-	chart_id = chart_ids;
-	obj = objects;
-	for ( ; obj != NULL ; obj = obj->next, chart_id = chart_id->next) {
-		anchor = sheet_object_get_anchor (obj->data);
-
-		gsf_xml_out_start_element (xml, "xdr:twoCellAnchor");
-		xlsx_write_object_anchor (xml, &anchor->cell_bound.start, "xdr:from");
-		xlsx_write_object_anchor (xml, &anchor->cell_bound.end, "xdr:to");
-
-		gsf_xml_out_start_element (xml, "xdr:graphicFrame");
-		gsf_xml_out_add_cstr_unchecked (xml, "macro", "");
-
-		gsf_xml_out_start_element (xml, "xdr:nvGraphicFramePr");
-
-		gsf_xml_out_start_element (xml, "xdr:cNvPr");
-		gsf_xml_out_add_int (xml, "id",  count+1);
-		gsf_xml_out_add_cstr_unchecked (xml, "name",
-			(tmp = g_strdup_printf ("Chart %d", count)));
-		g_free (tmp);
-		count++;
-		gsf_xml_out_end_element (xml);
-
-		gsf_xml_out_simple_element (xml, "xdr:cNvGraphicFramePr", NULL);
-		gsf_xml_out_end_element (xml); /* </xdr:nvGraphicFramePr> */
-
-		gsf_xml_out_start_element (xml, "xdr:xfrm");
-
-		gsf_xml_out_start_element (xml, "a:off");
-		gsf_xml_out_add_int (xml, "x", 0);
-		gsf_xml_out_add_int (xml, "y", 0);
-		gsf_xml_out_end_element (xml); /* </a:off> */
-
-		gsf_xml_out_start_element (xml, "a:ext");
-		gsf_xml_out_add_int (xml, "cx", 0);
-		gsf_xml_out_add_int (xml, "cy", 0);
-		gsf_xml_out_end_element (xml); /* </a:ext> */
-
-		gsf_xml_out_end_element (xml); /* </xdr:xfrm> */
-
-		gsf_xml_out_start_element (xml, "a:graphic");
-		gsf_xml_out_start_element (xml, "a:graphicData");
-		gsf_xml_out_add_cstr_unchecked (xml, "uri", ns_chart);
-		gsf_xml_out_start_element (xml, "c:chart");
-		gsf_xml_out_add_cstr_unchecked (xml, "xmlns:c", ns_chart);
-		gsf_xml_out_add_cstr_unchecked (xml, "xmlns:r", ns_rel);
-
-		gsf_xml_out_add_cstr_unchecked (xml, "r:id", chart_id->data);
-		gsf_xml_out_end_element (xml); /* </c:chart> */
-		gsf_xml_out_end_element (xml); /* </a:graphicData> */
-		gsf_xml_out_end_element (xml); /* </a:graphic> */
-		gsf_xml_out_end_element (xml); /* </xdr:graphicFrame> */
-		gsf_xml_out_simple_element (xml, "xdr:clientData", NULL);
-		gsf_xml_out_end_element (xml); /* </xdr:twoCellAnchor> */
-	}
-	g_slist_free (chart_ids);
-
-	gsf_xml_out_end_element (xml); /* </wsDr> */
-	g_object_unref (xml);
-	gsf_output_close (drawing_part);
-	g_object_unref (drawing_part);
-
-	return rId;
-}
-
-static void
 xlsx_write_rich_text (GsfXMLOut *xml, char const *text, PangoAttrList *attrs)
 {
 	PangoAttrIterator *iter =  pango_attr_list_get_iterator (attrs);
@@ -1465,6 +1058,8 @@ xlsx_write_comments (XLSXWriteState *state, GsfOutput *sheet_part, GSList *objec
 	g_object_unref (comments_part);
 }
 
+#include "xlsx-write-drawing.c"
+
 static char const *
 xlsx_write_sheet (XLSXWriteState *state, GsfOutfile *dir, GsfOutfile *wb_part, unsigned i)
 {



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