[gnumeric] Export basic charts to ODF.
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnumeric] Export basic charts to ODF.
- Date: Mon, 13 Jul 2009 05:07:37 +0000 (UTC)
commit 3279b8f775a7f97ca8a2e2bcf427a8255e099183
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date: Sun Jul 12 23:00:27 2009 -0600
Export basic charts to ODF.
2009-07-12 Andreas J. Guelzow <aguelzow pyrshep ca>
* openoffice-read.c (oo_chart_axis): use more of the
applicable styles
(oo_plot_area): ditto
(oo_plot_area_end): free GSList
(oo_chart): save applicable style
(openoffice_file_open): initialize chart.these_plot_styles
(od_draw_frame): calculate correct offsets
* openoffice-write.c (odf_write_bar_col_plot_style): new
(odf_write_bar_col_plot_styles): deleted
(odf_write_plot): try to implement basic support for all
plot types
(odf_write_bar_col_plot): deleted and incorporated in
odf_write_plot
NEWS | 2 +-
plugins/openoffice/ChangeLog | 16 ++++++
plugins/openoffice/openoffice-read.c | 45 +++++++++++++---
plugins/openoffice/openoffice-write.c | 96 +++++++++++++++++++++++++++------
4 files changed, 135 insertions(+), 24 deletions(-)
---
diff --git a/NEWS b/NEWS
index 82a8ff6..b8aec09 100644
--- a/NEWS
+++ b/NEWS
@@ -16,7 +16,7 @@ Andreas:
* Fix std error for intercept in non-affine case of LINEST. [#550933]
* Fix loading of charts from MS generated ODF files. [#588107]
* Add some sheet object support to ODF export.
- * Export column charts to ODF.
+ * Export basic charts to ODF.
Morten:
* Make SUMIF/COUNTIF and the D* functions understand pattern. [#586215]
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 0d0b507..41d6a38 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,19 @@
+2009-07-12 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * openoffice-read.c (oo_chart_axis): use more of the
+ applicable styles
+ (oo_plot_area): ditto
+ (oo_plot_area_end): free GSList
+ (oo_chart): save applicable style
+ (openoffice_file_open): initialize chart.these_plot_styles
+ (od_draw_frame): calculate correct offsets
+ * openoffice-write.c (odf_write_bar_col_plot_style): new
+ (odf_write_bar_col_plot_styles): deleted
+ (odf_write_plot): try to implement basic support for all
+ plot types
+ (odf_write_bar_col_plot): deleted and incorporated in
+ odf_write_plot
+
2009-07-10 Andreas J. Guelzow <aguelzow pyrshep ca>
* openoffice-write.c (odf_write_frame): also link to a png
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 3cb3749..1009568 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -144,7 +144,7 @@ typedef struct {
typedef struct {
gboolean grid; /* graph has grid? */
gboolean src_in_rows; /* orientation of graph data: rows or columns */
- GSList *axis_props; /* axis properties */
+ GSList *axis_props; /* axis properties */
GSList *plot_props; /* plot properties */
} OOChartStyle;
@@ -167,6 +167,7 @@ typedef struct {
OOChartStyle *cur_graph_style;
GHashTable *graph_styles; /* contain links to OOChartStyle GSLists */
+ GSList *these_plot_styles; /* */
OOPlotType plot_type;
SheetObjectAnchor anchor; /* anchor to draw the frame (images or graphs) */
} OOChartInfo;
@@ -3123,8 +3124,8 @@ od_draw_frame (GsfXMLIn *xin, xmlChar const **attrs)
frame_offset[0] = (x/col->size_pts);
frame_offset[1] = (y/row->size_pts);
- frame_offset[2] = (width/col->size_pts);
- frame_offset[3] = (height/row->size_pts);
+ frame_offset[2] = ((x+width)/col->size_pts);
+ frame_offset[3] = ((y+height)/row->size_pts);
sheet_object_anchor_init (&state->chart.anchor, &cell_base, frame_offset,
GOD_ANCHOR_DIR_DOWN_RIGHT);
}
@@ -3247,6 +3248,7 @@ oo_chart_axis (GsfXMLIn *xin, xmlChar const **attrs)
gchar const *style_name = NULL;
GogAxisType axis_type;
int tmp;
+ GSList *l;
axis_type = GOG_AXIS_UNKNOWN;
for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
@@ -3261,6 +3263,11 @@ oo_chart_axis (GsfXMLIn *xin, xmlChar const **attrs)
g_slist_free (axes);
}
+ for (l = state->chart.these_plot_styles; l != NULL; l = l->next) {
+ style = l->data;
+ oo_prop_list_apply (style->axis_props, G_OBJECT (state->chart.axis));
+ }
+
if (NULL != (style = g_hash_table_lookup (state->chart.graph_styles, style_name))) {
if (NULL != state->chart.axis)
oo_prop_list_apply (style->axis_props, G_OBJECT (state->chart.axis));
@@ -3287,10 +3294,15 @@ oo_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
OOChartStyle *style = NULL;
xmlChar const *source_range_str = NULL;
int label_flags = 0;
+ GSList *l;
for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
- if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_CHART, "style-name"))
- style = g_hash_table_lookup (state->chart.graph_styles, CXML2C (attrs[1]));
+ if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]),
+ OO_NS_CHART, "style-name"))
+ state->chart.these_plot_styles = g_slist_append
+ (state->chart.these_plot_styles,
+ g_hash_table_lookup
+ (state->chart.graph_styles, CXML2C (attrs[1])));
else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_TABLE, "cell-range-address"))
source_range_str = attrs[1];
else if (oo_attr_enum (xin, attrs, OO_NS_CHART, "data-source-has-labels", labels, &label_flags))
@@ -3316,8 +3328,10 @@ oo_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
if (label_flags & 2)
state->chart.src_range.start.col++;
- if (NULL != style)
+ for (l = state->chart.these_plot_styles; l != NULL; l = l->next) {
+ style = l->data;
state->chart.src_in_rows = style->src_in_rows;
+ }
if (state->chart.src_in_rows) {
state->chart.src_n_vectors = range_height (&state->chart.src_range);
state->chart.src_range.end.row = state->chart.src_range.start.row;
@@ -3345,8 +3359,10 @@ oo_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
state->chart.plot = gog_plot_new_by_name (type);
gog_object_add_by_name (GOG_OBJECT (state->chart.chart),
"Plot", GOG_OBJECT (state->chart.plot));
- if (style)
+ for (l = state->chart.these_plot_styles; l != NULL; l = l->next) {
+ style = l->data;
oo_prop_list_apply (style->plot_props, G_OBJECT (state->chart.plot));
+ }
}
static void
@@ -3354,6 +3370,8 @@ oo_plot_area_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
{
OOParseState *state = (OOParseState *)xin->user_state;
state->chart.plot = NULL;
+ g_slist_free (state->chart.these_plot_styles);
+ state->chart.these_plot_styles = NULL;
}
static int
@@ -3500,16 +3518,28 @@ oo_chart (GsfXMLIn *xin, xmlChar const **attrs)
OOParseState *state = (OOParseState *)xin->user_state;
int tmp;
OOPlotType type = OO_PLOT_SCATTER; /* arbitrary default */
+ OOChartStyle *style = NULL;
for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
if (oo_attr_enum (xin, attrs, OO_NS_CHART, "class", types, &tmp))
type = tmp;
+ else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]),
+ OO_NS_CHART, "style-name"))
+ state->chart.these_plot_styles = g_slist_append
+ (state->chart.these_plot_styles,
+ g_hash_table_lookup
+ (state->chart.graph_styles, CXML2C (attrs[1])));
state->chart.plot_type = type;
state->chart.chart = GOG_CHART (gog_object_add_by_name (
GOG_OBJECT (state->chart.graph), "Chart", NULL));
state->chart.plot = NULL;
state->chart.series = NULL;
state->chart.axis = NULL;
+ if (NULL != style)
+ state->chart.src_in_rows = style->src_in_rows;
+
+ /* if (NULL != style) we also need to save the style for later use in oo_plot_area */
+
}
static void
@@ -4835,6 +4865,7 @@ openoffice_file_open (GOFileOpener const *fo, IOContext *io_context,
state.pos.eval.col = -1;
state.pos.eval.row = -1;
state.cell_comment = NULL;
+ state.chart.these_plot_styles = NULL;
state.styles.sheet = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) g_free);
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index fa8db0d..a39673b 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -3168,6 +3168,18 @@ odf_write_series (GnmOOExport *state, GSList const *series)
}
static void
+odf_write_bar_col_plot_style (GnmOOExport *state, GogObject const *chart, GogObject const *plot)
+{
+ gboolean horizontal = FALSE;
+ if (plot == NULL)
+ return;
+
+ g_object_get (G_OBJECT (plot), "horizontal", &horizontal, NULL);
+ /* Note: horizontal refers to the bars and vertical to the x-axis */
+ odf_add_bool (state->xml, CHART "vertical", horizontal);
+}
+
+static void
odf_write_axis_style (GnmOOExport *state, GogObject const *chart, char const *axis_role,
char const *style_label)
{
@@ -3207,25 +3219,87 @@ odf_write_axis (GnmOOExport *state, GogObject const *chart, char const *axis_rol
}
static void
-odf_write_bar_col_plot_styles (GnmOOExport *state, GogObject const *chart, GogObject const *plot)
+odf_write_plot (GnmOOExport *state, GogObject const *chart, GogObject const *plot)
{
+
+ enum {
+ ODF_BARCOL,
+ ODF_LINE,
+ ODF_AREA,
+ ODF_DROPBAR,
+ ODF_MINMAX,
+ ODF_CIRCLE,
+ ODF_RADAR,
+ ODF_RADARAREA,
+ ODF_RING,
+ ODF_SCATTER,
+ ODF_SURF,
+ ODF_STOCK
+ } gtype;
+ char const *plot_type = G_OBJECT_TYPE_NAME (plot);
+ char const *odf_plot_type;
+
+ if (0 == strcmp (plot_type, "GogBarColPlot")) {
+ gtype = ODF_BARCOL;
+ odf_plot_type = "chart:bar";
+ } else if (0 == strcmp (plot_type, "GogLinePlot")) {
+ gtype = ODF_LINE;
+ odf_plot_type = "chart:line";
+ } else if (0 == strcmp (plot_type, "GogAreaPlot")) {
+ gtype = ODF_AREA;
+ odf_plot_type = "chart:area";
+ } else if (0 == strcmp (plot_type, "GogDropBarPlot")) {
+ gtype = ODF_DROPBAR;
+ odf_plot_type = "chart:bar";
+ } else if (0 == strcmp (plot_type, "GogMinMaxPlot")) {
+ gtype = ODF_STOCK;
+ odf_plot_type = "chart:stock";
+ } else if (0 == strcmp (plot_type, "GogPiePlot")) {
+ gtype = ODF_CIRCLE;
+ odf_plot_type = "chart:circle";
+ } else if (0 == strcmp (plot_type, "GogRadarPlot")) {
+ gtype = ODF_RADAR;
+ odf_plot_type = "chart:radar";
+ } else if (0 == strcmp (plot_type, "GogRadarAreaPlot")) {
+ gtype = ODF_RADARAREA;
+ odf_plot_type = "chart:radararea";
+ } else if (0 == strcmp (plot_type, "GogRingPlot")) {
+ gtype = ODF_RING;
+ odf_plot_type = "chart:ring";
+ } else if (0 == strcmp (plot_type, "GogXYPlot")) {
+ gtype = ODF_SCATTER;
+ odf_plot_type = "chart:scatter";
+ } else if (0 == strcmp (plot_type, "GogContourPlot")) {
+ gtype = ODF_SURF;
+ odf_plot_type = "chart:surface";
+ } else {
+ g_print ("encountered unknown chart type %s\n", plot_type);
+ gtype = ODF_BARCOL;
+ odf_plot_type = "GogBarColPlot";
+ }
+
gsf_xml_out_start_element (state->xml, OFFICE "automatic-styles");
odf_write_axis_style (state, chart, "Y-Axis", "yaxis");
odf_write_axis_style (state, chart, "X-Axis", "xaxis");
+ odf_start_style (state->xml, "plotstyle", "chart");
+ gsf_xml_out_start_element (state->xml, STYLE "chart-properties");
+ if (gtype == ODF_BARCOL)
+ odf_write_bar_col_plot_style (state, chart, plot);
+
+ gsf_xml_out_end_element (state->xml); /* </style:chart-properties> */
+ gsf_xml_out_end_element (state->xml); /* </style:style> */
gsf_xml_out_end_element (state->xml); /* </office:automatic-styles> */
-}
-static void
-odf_write_bar_col_plot (GnmOOExport *state, GogObject const *chart, GogObject const *plot)
-{
gsf_xml_out_start_element (state->xml, OFFICE "body");
gsf_xml_out_start_element (state->xml, OFFICE "chart");
gsf_xml_out_start_element (state->xml, CHART "chart");
if (get_gsf_odf_version () > 101)
gsf_xml_out_add_cstr (state->xml, XLINK "href", "..");
- gsf_xml_out_add_cstr (state->xml, CHART "class", "chart:bar");
+ gsf_xml_out_add_cstr (state->xml, CHART "class", odf_plot_type);
+ gsf_xml_out_add_cstr (state->xml, CHART "style-name", "plotstyle");
gsf_xml_out_start_element (state->xml, CHART "plot-area");
+ gsf_xml_out_add_cstr (state->xml, CHART "style-name", "plotstyle");
if (get_gsf_odf_version () <= 101) {
GSList const *series = gog_plot_get_series (GOG_PLOT (plot));
for ( ; NULL != series ; series = series->next) {
@@ -3254,16 +3328,6 @@ odf_write_bar_col_plot (GnmOOExport *state, GogObject const *chart, GogObject co
gsf_xml_out_end_element (state->xml); /* </office:body> */
}
-static void
-odf_write_plot (GnmOOExport *state, GogObject const *chart, GogObject const *plot)
-{
- char const *plot_type = G_OBJECT_TYPE_NAME (plot);
- if (0 == strcmp (plot_type, "GogBarColPlot")) {
- odf_write_bar_col_plot_styles (state, chart, plot);
- odf_write_bar_col_plot (state, chart, plot);
- }
-}
-
static void
odf_write_graph_content (GnmOOExport *state, GsfOutput *child, SheetObject *so)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]