[goffice] Implement error bars in radar and polar plots. [#572720]
- From: Jean Bréfort <jbrefort src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [goffice] Implement error bars in radar and polar plots. [#572720]
- Date: Wed, 4 Nov 2009 18:42:35 +0000 (UTC)
commit 1191c1332ceff0f173b0c5386a8cbb1306f9d216
Author: Jean Brefort <jean brefort normalesup org>
Date: Wed Nov 4 19:42:53 2009 +0100
Implement error bars in radar and polar plots. [#572720]
ChangeLog | 23 +++
NEWS | 1 +
goffice/graph/gog-error-bar-prefs.ui | 3 +-
goffice/graph/gog-error-bar.c | 126 ++++++++++++++--
goffice/graph/gog-error-bar.h | 13 ++-
plugins/plot_barcol/gog-barcol.c | 4 +-
plugins/plot_barcol/gog-line.c | 4 +-
plugins/plot_radar/gog-radar.c | 274 +++++++++++++++++++++++++++++++++-
plugins/plot_xy/gog-xy.c | 10 +-
9 files changed, 425 insertions(+), 33 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 2c6c44e..6afa86a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,28 @@
2009-11-04 Jean Brefort <jean brefort normalesup org>
+ * goffice/graph/gog-error-bar-prefs.ui: implement error bars in
+ radar and polar plots. [#572720]
+ * goffice/graph/gog-error-bar.c (gog_error_bar_prefs),
+ (gog_error_bar_render): ditto.
+ * goffice/graph/gog-error-bar.h: ditto.
+ * plugins/plot_barcol/gog-barcol.c (gog_barcol_view_render): fixed after
+ error bars API changes.
+ * plugins/plot_barcol/gog-line.c (gog_line_view_render): ditto.
+ * plugins/plot_radar/gog-radar.c (gog_rt_plot_update),
+ (gog_radar_plot_class_init), (gog_polar_plot_class_init),
+ (gog_color_polar_plot_class_init), (gog_rt_view_render),
+ (gog_rt_series_set_property), (gog_rt_series_get_property),
+ (gog_rt_series_finalize), (gog_rt_series_populate_editor),
+ (gog_rt_series_class_init), (gog_polar_series_set_property),
+ (gog_polar_series_get_property),
+ (gog_polar_series_populate_editor), (gog_polar_series_finalize),
+ (gog_polar_series_class_init): implement error bars in
+ radar and polar plots. [#572720]
+ * plugins/plot_xy/gog-xy.c (gog_xy_view_render): fixed after
+ error bars API changes.
+
+2009-11-04 Jean Brefort <jean brefort normalesup org>
+
* goffice/app/go-conf-keyfile.c (go_conf_get_real_key): do not add a '/'
when subkey is NULL. [#600654]
diff --git a/NEWS b/NEWS
index bed17a8..83bb208 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ goffice 0.7.16:
Jean:
* Add parent name for new objects in the graph guru "Add" menu.
* Fix configuratioin loading when using .gnumericrc. [#600654]
+ * Implement error bars in radar and polar plots. [#572720]
--------------------------------------------------------------------------
goffice 0.7.15:
diff --git a/goffice/graph/gog-error-bar-prefs.ui b/goffice/graph/gog-error-bar-prefs.ui
index c180be9..e0d66fd 100644
--- a/goffice/graph/gog-error-bar-prefs.ui
+++ b/goffice/graph/gog-error-bar-prefs.ui
@@ -1,5 +1,6 @@
<?xml version="1.0"?>
<interface>
+ <!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkAdjustment" id="adjustment1">
<property name="value">1</property>
@@ -218,7 +219,7 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="label1">
+ <object class="GtkLabel" id="width-label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">pts</property>
diff --git a/goffice/graph/gog-error-bar.c b/goffice/graph/gog-error-bar.c
index 401dbbe..d678e23 100644
--- a/goffice/graph/gog-error-bar.c
+++ b/goffice/graph/gog-error-bar.c
@@ -198,7 +198,7 @@ cb_type_changed (GtkWidget *w, GogErrorBarEditor *editor)
gpointer
gog_error_bar_prefs (GogSeries *series,
char const *property,
- gboolean horizontal,
+ GogErrorBarDirection direction,
GogDataAllocator *dalloc,
GOCmdContext *cc)
{
@@ -276,7 +276,7 @@ gog_error_bar_prefs (GogSeries *series,
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell, "text", 1, NULL);
for (i = 0; i < G_N_ELEMENTS (display_combo_desc); i++) {
- pixbuf = go_pixbuf_new_from_file (horizontal ?
+ pixbuf = go_pixbuf_new_from_file (direction == GOG_ERROR_BAR_DIRECTION_HORIZONTAL ?
display_combo_desc[i].h_pixbuf :
display_combo_desc[i].v_pixbuf);
gtk_list_store_append (list, &iter);
@@ -293,6 +293,13 @@ gog_error_bar_prefs (GogSeries *series,
gtk_table_attach (GTK_TABLE (style_table), GTK_WIDGET(combo), 1, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (cb_display_changed), editor);
+ /* if radial, change the width unit */
+ if (direction == GOG_ERROR_BAR_DIRECTION_RADIAL) {
+ w = go_gtk_builder_get_widget (gui, "width-label");
+ /* Note for translator: the angle unit */
+ gtk_label_set_text (GTK_LABEL (w), _("°"));
+ }
+
/* Category property*/
w = go_gtk_builder_get_widget (gui, "category_combo");
gtk_combo_box_set_active (GTK_COMBO_BOX (w), (editor->bar)? (int) editor->bar->type: 0);
@@ -615,13 +622,12 @@ gog_error_bar_dup (GogErrorBar const *bar)
* gog_error_bar_render :
* @bar : A GogErrorBar
* @rend : A GogRenderer
- * @x_map : A GogAxisMap for the x axis
- * @y_map : A GogAxisMap for the y axis
+ * @map : A GogChartMap for the chart
* @x : x coordinate of the origin of the bar
* @y : y coordinate of the origin of the bar
* @plus : distance from the origin to the positive end of the bar
* @minus : distance from the origin to the negative end of the bar
- * @horizontal : whether the bar is horizontal or not.
+ * @direction : the #GogErrorBarDirection for the bar.
*
* Displays the error bar. If @plus is negative, the positive side of the bar is not displayed,
* and if @minus is negative, the negative side of the bar is not displayed.
@@ -630,21 +636,25 @@ gog_error_bar_dup (GogErrorBar const *bar)
**/
void gog_error_bar_render (const GogErrorBar *bar,
GogRenderer *rend,
- GogAxisMap *x_map, GogAxisMap *y_map,
+ GogChartMap *map,
double x, double y,
double minus,
double plus,
- gboolean horizontal)
+ GogErrorBarDirection direction)
{
GOPath *path;
double x_start, y_start, x_end, y_end;
double line_width, width;
- gboolean start = plus > .0 && bar ->display & GOG_ERROR_BAR_DISPLAY_POSITIVE,
- end = minus > 0. && bar ->display & GOG_ERROR_BAR_DISPLAY_NEGATIVE;
+ gboolean start = plus > .0 && bar->display & GOG_ERROR_BAR_DISPLAY_POSITIVE,
+ end = minus > 0. && bar->display & GOG_ERROR_BAR_DISPLAY_NEGATIVE;
+ GogAxisMap *x_map = gog_chart_map_get_axis_map (map, 0),
+ *y_map = gog_chart_map_get_axis_map (map, 1);
- if (!start && !end) return;
+ if (!start && !end)
+ return;
- if (horizontal) {
+ switch (direction) {
+ case GOG_ERROR_BAR_DIRECTION_HORIZONTAL:
if (!gog_axis_map_finite (x_map, x) ||
!gog_axis_map_finite (y_map, y) ||
(start && !gog_axis_map_finite (x_map, x + plus)) ||
@@ -658,7 +668,8 @@ void gog_error_bar_render (const GogErrorBar *bar,
gog_axis_map_to_view (x_map , x - minus) :
gog_axis_map_to_view (x_map , x);
y_start = y_end = gog_axis_map_to_view (y_map, y);
- } else {
+ break;
+ case GOG_ERROR_BAR_DIRECTION_VERTICAL:
if (!gog_axis_map_finite (x_map, x) ||
!gog_axis_map_finite (y_map, y) ||
(start && !gog_axis_map_finite (y_map, y + plus)) ||
@@ -672,6 +683,93 @@ void gog_error_bar_render (const GogErrorBar *bar,
y_end = end ?
gog_axis_map_to_view (y_map, y - minus) :
gog_axis_map_to_view (y_map, y);
+ break;
+ case GOG_ERROR_BAR_DIRECTION_RADIAL: {
+ GogChartMapPolarData *polar_parms;
+ double cx, cy;
+ double a, rr, xx, yy, y_min, y_max;
+ gboolean cap_min, cap_max;
+ /* x = angle, y = radius */
+ polar_parms = gog_chart_map_get_polar_parms (map);
+ cx = polar_parms->cx;
+ cy = polar_parms->cy;
+ gog_axis_map_get_bounds (y_map, &y_min, &y_max);
+ width = gog_renderer_pt2r (rend, bar->width) / 2.;
+ if (start && y + plus > y_max) {
+ plus = y_max - y;
+ cap_max = FALSE;
+ } else
+ cap_max = TRUE;
+ if (end && y - minus < y_min) {
+ minus = y -y_min;
+ cap_min = FALSE;
+ } else
+ cap_min = TRUE;
+
+ gog_chart_map_2D_to_view (map, x, (start ? y + plus : y),
+ &xx, &yy);
+ path = go_path_new ();
+ if (start && cap_max) {
+ rr = hypot (xx - cx, yy - cy);
+ a = atan2 (yy - cy, xx - cx);
+ go_path_arc (path, cx, cy, rr, rr, a - width * M_PI / 180., a + width * M_PI / 180.);
+ }
+ go_path_move_to (path, xx, yy);
+ gog_chart_map_2D_to_view (map, x, (end ? y - minus : y),
+ &xx, &yy);
+ go_path_line_to (path, xx, yy);
+ if (end && cap_min) {
+ rr = hypot (xx - cx, yy - cy);
+ a = atan2 (yy - cy, xx - cx);
+ go_path_arc (path, cx, cy, rr, rr, a - width * M_PI / 180., a + width * M_PI / 180.);
+ }
+ gog_renderer_push_style (rend, bar->style);
+ gog_renderer_stroke_serie (rend, path);
+ gog_renderer_pop_style (rend);
+ go_path_free (path);
+ return;
+ }
+ case GOG_ERROR_BAR_DIRECTION_ANGULAR: {
+ GogChartMapPolarData *polar_parms;
+ double cx, cy, a0, x0, y0, a1, x1, y1, rr, y_min, y_max;
+ polar_parms = gog_chart_map_get_polar_parms (map);
+ cx = polar_parms->cx;
+ cy = polar_parms->cy;
+ gog_axis_map_get_bounds (y_map, &y_min, &y_max);
+ if (y < y_min || y > y_max)
+ return;
+ width = gog_renderer_pt2r (rend, bar->width) / 2.;
+ line_width = gog_renderer_pt2r (rend, bar->style->line.width);
+ gog_chart_map_2D_to_view (map, (start ? x + plus : x), y,
+ &x0, &y0);
+ rr = hypot (x0 - cx, y0 - cy);
+ if (rr == 0.)
+ return;
+ a0 = atan2 (y0 - cy, x0 - cx);
+ path = go_path_new ();
+ gog_chart_map_2D_to_view (map, (end ? x - minus : x), y,
+ &x1, &y1);
+ a1 = atan2 (y1 - cy, x1 - cx);
+ go_path_arc (path, cx, cy, rr, rr, a1, a0);
+ if ((2. * width) > line_width) {
+ double dx, dy;
+ dx = width * cos (a0);
+ dy = width * sin (a0);
+ go_path_move_to (path, x0 - dx, y0 - dy);
+ go_path_line_to (path, x0 + dx, y0 + dy);
+ dx = width * cos (a1);
+ dy = width * sin (a1);
+ go_path_move_to (path, x1 - dx, y1 - dy);
+ go_path_line_to (path, x1 + dx, y1 + dy);
+ }
+ gog_renderer_push_style (rend, bar->style);
+ gog_renderer_stroke_serie (rend, path);
+ gog_renderer_pop_style (rend);
+ go_path_free (path);
+ return;
+ }
+ default:
+ return; /* should not occur */
}
x = gog_axis_map_to_view (x_map, x);
y = gog_axis_map_to_view (y_map, y);
@@ -680,7 +778,7 @@ void gog_error_bar_render (const GogErrorBar *bar,
go_path_move_to (path, x_start, y_start);
go_path_line_to (path, x_end, y_end);
- if (horizontal) {
+ if (direction == GOG_ERROR_BAR_DIRECTION_HORIZONTAL) {
width = gog_renderer_pt2r_y (rend, bar->width) / 2.;
line_width = gog_renderer_pt2r_x (rend, bar->style->line.width);
} else {
@@ -689,7 +787,7 @@ void gog_error_bar_render (const GogErrorBar *bar,
}
if ((2. * width) > line_width) {
- if (horizontal) {
+ if (direction == GOG_ERROR_BAR_DIRECTION_HORIZONTAL) {
if (start) {
go_path_move_to (path, x_start, y - width);
go_path_line_to (path, x_start, y + width);
diff --git a/goffice/graph/gog-error-bar.h b/goffice/graph/gog-error-bar.h
index e0689bb..a7fe992 100644
--- a/goffice/graph/gog-error-bar.h
+++ b/goffice/graph/gog-error-bar.h
@@ -34,6 +34,13 @@ typedef enum {
} GogErrorBarType;
typedef enum {
+ GOG_ERROR_BAR_DIRECTION_HORIZONTAL,
+ GOG_ERROR_BAR_DIRECTION_VERTICAL,
+ GOG_ERROR_BAR_DIRECTION_ANGULAR,
+ GOG_ERROR_BAR_DIRECTION_RADIAL
+} GogErrorBarDirection;
+
+typedef enum {
GOG_ERROR_BAR_DISPLAY_NONE,
GOG_ERROR_BAR_DISPLAY_POSITIVE,
GOG_ERROR_BAR_DISPLAY_NEGATIVE,
@@ -61,7 +68,7 @@ GogErrorBar *gog_error_bar_dup (GogErrorBar const *bar);
#ifdef GOFFICE_WITH_GTK
gpointer gog_error_bar_prefs (GogSeries *series, char const *property,
- gboolean horizontal, GogDataAllocator *dalloc,
+ GogErrorBarDirection direction, GogDataAllocator *dalloc,
GOCmdContext *cc);
#endif
@@ -70,11 +77,11 @@ gboolean gog_error_bar_get_bounds (const GogErrorBar *bar, int index,
void gog_error_bar_get_minmax (const GogErrorBar *bar,
double *min, double *max);
void gog_error_bar_render (const GogErrorBar *bar, GogRenderer *rend,
- GogAxisMap *x_map, GogAxisMap *y_map,
+ GogChartMap *map,
double x, double y,
double minus,
double plus,
- gboolean horizontal);
+ GogErrorBarDirection direction);
gboolean gog_error_bar_is_visible (GogErrorBar *bar);
G_END_DECLS
diff --git a/plugins/plot_barcol/gog-barcol.c b/plugins/plot_barcol/gog-barcol.c
index 2dfc3b2..f9b3732 100644
--- a/plugins/plot_barcol/gog-barcol.c
+++ b/plugins/plot_barcol/gog-barcol.c
@@ -547,10 +547,10 @@ gog_barcol_view_render (GogView *view, GogViewAllocation const *bbox)
if (gog_error_bar_is_visible (errors[i])) {
for (j = 0; j < lengths[i]; j++)
gog_error_bar_render (errors[i], view->renderer,
- x_map, y_map,
+ chart_map,
error_data[i][j].x , error_data[i][j].y,
error_data[i][j].minus, error_data[i][j].plus,
- model->horizontal);
+ model->horizontal? GOG_ERROR_BAR_DIRECTION_HORIZONTAL: GOG_ERROR_BAR_DIRECTION_VERTICAL);
g_free (error_data[i]);
}
diff --git a/plugins/plot_barcol/gog-line.c b/plugins/plot_barcol/gog-line.c
index de830c6..eb9a591 100644
--- a/plugins/plot_barcol/gog-line.c
+++ b/plugins/plot_barcol/gog-line.c
@@ -677,10 +677,10 @@ gog_line_view_render (GogView *view, GogViewAllocation const *bbox)
for (i = 0; i < num_series; i++)
if (gog_error_bar_is_visible (errors[i]))
for (j = 0; j < lengths[i]; j++)
- gog_error_bar_render (errors[i], view->renderer, x_map, y_map,
+ gog_error_bar_render (errors[i], view->renderer, chart_map,
error_data[i][j].x, error_data[i][j].y,
error_data[i][j].minus, error_data[i][j].plus,
- FALSE);
+ GOG_ERROR_BAR_DIRECTION_VERTICAL);
gog_renderer_pop_clip (view->renderer);
diff --git a/plugins/plot_radar/gog-radar.c b/plugins/plot_radar/gog-radar.c
index 9b1a53e..ee1a674 100644
--- a/plugins/plot_radar/gog-radar.c
+++ b/plugins/plot_radar/gog-radar.c
@@ -25,6 +25,7 @@
#include <goffice/graph/gog-axis.h>
#include <goffice/graph/gog-chart.h>
#include <goffice/graph/gog-chart-map.h>
+#include <goffice/graph/gog-error-bar.h>
#include <goffice/graph/gog-grid-line.h>
#include <goffice/graph/gog-view.h>
#include <goffice/graph/gog-renderer.h>
@@ -63,10 +64,14 @@ GOFFICE_PLUGIN_MODULE_HEADER;
typedef struct {
GogSeries base;
GogObject *radial_drop_lines;
+ GogErrorBar *r_errors;
} GogRTSeries;
-typedef GogRTSeries GogPolarSeries;
-typedef GogRTSeries GogColorPolarSeries;
+typedef struct {
+ GogRTSeries base;
+ GogErrorBar *a_errors;
+} GogPolarSeries;
+typedef GogPolarSeries GogColorPolarSeries;
typedef GogSeriesClass GogRTSeriesClass;
typedef GogRTSeriesClass GogPolarSeriesClass;
@@ -82,6 +87,11 @@ enum {
#define GOG_IS_RT_SERIES(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_TYPE_RT_SERIES))
static GType gog_rt_series_get_type (void);
+
+#define GOG_TYPE_POLAR_SERIES (gog_polar_series_get_type ())
+#define GOG_POLAR_SERIES(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_TYPE_POLAR_SERIES, GogPolarSeries))
+#define GOG_IS_POLAR_SERIES(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_TYPE_POLAR_SERIES))
+
static GType gog_polar_series_get_type (void);
static GType gog_color_polar_series_get_type (void);
static GType gog_rt_view_get_type (void);
@@ -146,6 +156,7 @@ gog_rt_plot_update (GogObject *obj)
unsigned num_elements = 0;
double val_min, val_max, tmp_min, tmp_max;
GSList *ptr;
+ GogErrorBar *errors;
val_min = DBL_MAX;
val_max = -DBL_MAX;
@@ -159,6 +170,15 @@ gog_rt_plot_update (GogObject *obj)
go_data_get_bounds (series->base.values[1].data, &tmp_min, &tmp_max);
if (val_min > tmp_min) val_min = tmp_min;
if (val_max < tmp_max) val_max = tmp_max;
+
+ errors = series->r_errors;
+ if (gog_error_bar_is_visible (errors)) {
+ gog_error_bar_get_minmax (errors, &tmp_min, &tmp_max);
+ if (val_min > tmp_min)
+ val_min = tmp_min;
+ if (val_max < tmp_max)
+ val_max = tmp_max;
+ }
}
model->num_elements = num_elements;
@@ -299,7 +319,11 @@ gog_radar_plot_class_init (GogPlotClass *gog_plot_klass)
{ N_("Labels"), GOG_SERIES_SUGGESTED, TRUE,
GOG_DIM_LABEL, GOG_MS_DIM_CATEGORIES },
{ N_("Values"), GOG_SERIES_REQUIRED, FALSE,
- GOG_DIM_VALUE, GOG_MS_DIM_VALUES }
+ GOG_DIM_VALUE, GOG_MS_DIM_VALUES },
+ { "Magnitude+err", GOG_SERIES_ERRORS, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_ERR_plus1 },
+ { "Magnitude-err", GOG_SERIES_ERRORS, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_ERR_minus1 }
};
gog_plot_klass->desc.series.dim = dimensions;
gog_plot_klass->desc.series.num_dim = G_N_ELEMENTS (dimensions);
@@ -406,7 +430,16 @@ gog_polar_plot_class_init (GogPlotClass *gog_plot_klass)
{ N_("Angle"), GOG_SERIES_SUGGESTED, FALSE,
GOG_DIM_INDEX, GOG_MS_DIM_CATEGORIES },
{ N_("Magnitude"), GOG_SERIES_REQUIRED, FALSE,
- GOG_DIM_VALUE, GOG_MS_DIM_VALUES }
+ GOG_DIM_VALUE, GOG_MS_DIM_VALUES },
+/* Names of the error data are not translated since they are not used */
+ { "Angle+err", GOG_SERIES_ERRORS, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_ERR_plus2 },
+ { "Angle-err", GOG_SERIES_ERRORS, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_ERR_minus2 },
+ { "Magnitude+err", GOG_SERIES_ERRORS, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_ERR_plus1 },
+ { "Magnitude-err", GOG_SERIES_ERRORS, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_ERR_minus1 }
};
gog_plot_klass->desc.series.dim = dimensions;
gog_plot_klass->desc.series.num_dim = G_N_ELEMENTS (dimensions);
@@ -607,7 +640,15 @@ gog_color_polar_plot_class_init (GogPlotClass *gog_plot_klass)
{ N_("Magnitude"), GOG_SERIES_REQUIRED, FALSE,
GOG_DIM_VALUE, GOG_MS_DIM_VALUES },
{ N_("Z"), GOG_SERIES_REQUIRED, FALSE,
- GOG_DIM_VALUE, GOG_MS_DIM_EXTRA1 }
+ GOG_DIM_VALUE, GOG_MS_DIM_EXTRA1 },
+ { "Angle+err", GOG_SERIES_ERRORS, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_ERR_plus2 },
+ { "Angle-err", GOG_SERIES_ERRORS, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_ERR_minus2 },
+ { "Magnitude+err", GOG_SERIES_ERRORS, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_ERR_plus1 },
+ { "Magnitude-err", GOG_SERIES_ERRORS, FALSE,
+ GOG_DIM_VALUE, GOG_MS_DIM_ERR_minus1 }
};
gog_plot_klass->desc.series.dim = dimensions;
gog_plot_klass->desc.series.num_dim = G_N_ELEMENTS (dimensions);
@@ -671,6 +712,7 @@ gog_rt_view_render (GogView *view, GogViewAllocation const *bbox)
double rho_min, rho_max, rho;
gboolean const is_polar = GOG_IS_PLOT_POLAR (model);
gboolean is_map = GOG_IS_PLOT_COLOR_POLAR (model), hide_outliers = TRUE;
+ double errmin, errmax;
r_axis = GOG_PLOT (model)->axis[GOG_AXIS_RADIAL];
c_axis = GOG_PLOT (model)->axis[GOG_AXIS_CIRCULAR];
@@ -803,7 +845,8 @@ gog_rt_view_render (GogView *view, GogViewAllocation const *bbox)
r_vals[i], &theta, &rho);
if ( go_finite (theta)
&& go_finite (rho)
- && rho > rho_min) {
+ && r_vals[i] > rho_min
+ && r_vals[i] <= rho_max) {
go_path_move_to (drop_path, parms->cx, parms->cy);
go_path_line_to (drop_path, theta, rho);
}
@@ -818,6 +861,33 @@ gog_rt_view_render (GogView *view, GogViewAllocation const *bbox)
go_path_free (path);
}
+ /* draw error bars before markers and after anything else */
+ for (count = 0; count < series->base.num_elements; count++)
+ if (gog_error_bar_is_visible (series->r_errors)) {
+ GogErrorBar const *bar = series->r_errors;
+ if (gog_error_bar_get_bounds (bar, count, &errmin, &errmax)) {
+ gog_error_bar_render (bar, view->renderer,
+ chart_map,
+ ((c_vals != NULL) ? c_vals[count] : count + 1), r_vals[count],
+ errmin, errmax,
+ GOG_ERROR_BAR_DIRECTION_RADIAL);
+ }
+ }
+ if (GOG_IS_POLAR_SERIES (series)) {
+ GogPolarSeries *polar_series = GOG_POLAR_SERIES (series);
+ for (count = 0; count < series->base.num_elements; count++)
+ if (gog_error_bar_is_visible (polar_series->a_errors)) {
+ GogErrorBar const *bar = polar_series->a_errors;
+ if (gog_error_bar_get_bounds (bar, count, &errmin, &errmax)) {
+ gog_error_bar_render (bar, view->renderer,
+ chart_map,
+ c_vals[count], r_vals[count],
+ errmin, errmax,
+ GOG_ERROR_BAR_DIRECTION_ANGULAR);
+ }
+ }
+ }
+
if (is_polar)
gog_renderer_pop_clip (view->renderer);
@@ -910,6 +980,11 @@ radial_drop_lines_pre_remove (GogObject *parent, GogObject *child)
static GogStyledObjectClass *series_parent_klass;
+enum {
+ RT_SERIES_PROP_0,
+ RT_SERIES_PROP_RERRORS,
+};
+
static void
gog_rt_series_update (GogObject *obj)
{
@@ -966,6 +1041,81 @@ gog_rt_series_init_style (GogStyledObject *gso, GOStyle *style)
}
static void
+gog_rt_series_set_property (GObject *obj, guint param_id,
+ GValue const *value, GParamSpec *pspec)
+{
+ GogRTSeries *series= GOG_RT_SERIES (obj);
+ GogErrorBar* bar;
+
+ switch (param_id) {
+ case RT_SERIES_PROP_RERRORS :
+ bar = g_value_get_object (value);
+ if (series->r_errors == bar)
+ return;
+ if (bar) {
+ bar = gog_error_bar_dup (bar);
+ bar->series = GOG_SERIES (series);
+ bar->dim_i = 1;
+ bar->error_i = series->base.plot->desc.series.num_dim - 2;
+ }
+ if (!series->base.needs_recalc) {
+ series->base.needs_recalc = TRUE;
+ gog_object_emit_changed (GOG_OBJECT (series), FALSE);
+ }
+ if (series->r_errors != NULL)
+ g_object_unref (series->r_errors);
+ series->r_errors = bar;
+ break;
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+gog_rt_series_get_property (GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GogRTSeries *series= GOG_RT_SERIES (obj);
+
+ switch (param_id) {
+ case RT_SERIES_PROP_RERRORS :
+ g_value_set_object (value, series->r_errors);
+ break;
+ break;
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+gog_rt_series_finalize (GObject *obj)
+{
+ GogRTSeries *series = GOG_RT_SERIES (obj);
+
+ if (series->r_errors != NULL) {
+ g_object_unref (series->r_errors);
+ series->r_errors = NULL;
+ }
+
+ G_OBJECT_CLASS (series_parent_klass)->finalize (obj);
+}
+
+#ifdef GOFFICE_WITH_GTK
+static void
+gog_rt_series_populate_editor (GogObject *obj,
+ GOEditor *editor,
+ GogDataAllocator *dalloc,
+ GOCmdContext *cc)
+{
+ GtkWidget *w;
+ (GOG_OBJECT_CLASS(series_parent_klass)->populate_editor) (obj, editor, dalloc, cc);
+
+ w = gog_error_bar_prefs (GOG_SERIES (obj), "r-errors", GOG_ERROR_BAR_DIRECTION_RADIAL, dalloc, cc);
+ go_editor_add_page (editor, w, _("Radial error bars"));
+}
+#endif
+
+static void
gog_rt_series_class_init (GogStyledObjectClass *gso_klass)
{
static GogObjectRole const roles[] = {
@@ -979,12 +1129,25 @@ gog_rt_series_class_init (GogStyledObjectClass *gso_klass)
NULL }
};
+ GObjectClass *gobject_klass = G_OBJECT_CLASS (gso_klass);
GogObjectClass *obj_klass = GOG_OBJECT_CLASS (gso_klass);
GogSeriesClass *series_klass = GOG_SERIES_CLASS (gso_klass);
series_parent_klass = g_type_class_peek_parent (gso_klass);
gso_klass->init_style = gog_rt_series_init_style;
+ gobject_klass->finalize = gog_rt_series_finalize;
+ gobject_klass->set_property = gog_rt_series_set_property;
+ gobject_klass->get_property = gog_rt_series_get_property;
obj_klass->update = gog_rt_series_update;
+#ifdef GOFFICE_WITH_GTK
+ obj_klass->populate_editor = gog_rt_series_populate_editor;
+#endif
+ g_object_class_install_property (gobject_klass, RT_SERIES_PROP_RERRORS,
+ g_param_spec_object ("r-errors",
+ _("Radial error bars"),
+ _("GogErrorBar *"),
+ GOG_TYPE_ERROR_BAR,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
series_klass->has_interpolation = TRUE;
@@ -997,6 +1160,89 @@ GSF_DYNAMIC_CLASS (GogRTSeries, gog_rt_series,
/*****************************************************************************/
+static GObjectClass *polar_series_parent_klass;
+
+enum {
+ POLAR_SERIES_PROP_0,
+ POLAR_SERIES_PROP_AERRORS,
+};
+
+/*****************************************************************************/
+
+static void
+gog_polar_series_set_property (GObject *obj, guint param_id,
+ GValue const *value, GParamSpec *pspec)
+{
+ GogPolarSeries *series= GOG_POLAR_SERIES (obj);
+ GogErrorBar* bar;
+
+ switch (param_id) {
+ case POLAR_SERIES_PROP_AERRORS :
+ bar = g_value_get_object (value);
+ if (series->a_errors == bar)
+ return;
+ if (bar) {
+ bar = gog_error_bar_dup (bar);
+ bar->series = GOG_SERIES (series);
+ bar->dim_i = 0;
+ bar->error_i = series->base.base.plot->desc.series.num_dim - 4;
+ }
+ if (!series->base.base.needs_recalc) {
+ series->base.base.needs_recalc = TRUE;
+ gog_object_emit_changed (GOG_OBJECT (series), FALSE);
+ }
+ if (series->a_errors != NULL)
+ g_object_unref (series->a_errors);
+ series->a_errors = bar;
+ break;
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+gog_polar_series_get_property (GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GogPolarSeries *series= GOG_POLAR_SERIES (obj);
+
+ switch (param_id) {
+ case POLAR_SERIES_PROP_AERRORS :
+ g_value_set_object (value, series->a_errors);
+ break;
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
+ break;
+ }
+}
+
+#ifdef GOFFICE_WITH_GTK
+static void
+gog_polar_series_populate_editor (GogObject *obj,
+ GOEditor *editor,
+ GogDataAllocator *dalloc,
+ GOCmdContext *cc)
+{
+ GtkWidget *w;
+ (GOG_OBJECT_CLASS(polar_series_parent_klass)->populate_editor) (obj, editor, dalloc, cc);
+
+ w = gog_error_bar_prefs (GOG_SERIES (obj), "a-errors", GOG_ERROR_BAR_DIRECTION_ANGULAR, dalloc, cc);
+ go_editor_add_page (editor, w, _("Angular error bars"));
+}
+#endif
+
+static void
+gog_polar_series_finalize (GObject *obj)
+{
+ GogPolarSeries *series = GOG_POLAR_SERIES (obj);
+
+ if (series->a_errors != NULL) {
+ g_object_unref (series->a_errors);
+ series->a_errors = NULL;
+ }
+
+ G_OBJECT_CLASS (polar_series_parent_klass)->finalize (obj);
+}
+
static void
gog_polar_series_class_init (GogObjectClass *gog_klass)
{
@@ -1009,10 +1255,24 @@ gog_polar_series_class_init (GogObjectClass *gog_klass)
GOG_SERIES_FILL_TYPE_INVALID
};
+ GObjectClass *gobject_klass = G_OBJECT_CLASS (gog_klass);
GogSeriesClass *series_klass = GOG_SERIES_CLASS (gog_klass);
+ polar_series_parent_klass = g_type_class_peek_parent (gog_klass);
series_klass->has_fill_type = TRUE;
series_klass->valid_fill_type_list = valid_fill_type_list;
+ gobject_klass->finalize = gog_polar_series_finalize;
+ gobject_klass->set_property = gog_polar_series_set_property;
+ gobject_klass->get_property = gog_polar_series_get_property;
+#ifdef GOFFICE_WITH_GTK
+ gog_klass->populate_editor = gog_polar_series_populate_editor;
+#endif
+ g_object_class_install_property (gobject_klass, POLAR_SERIES_PROP_AERRORS,
+ g_param_spec_object ("a-errors",
+ _("Angular error bars"),
+ _("GogErrorBar *"),
+ GOG_TYPE_ERROR_BAR,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
}
GSF_DYNAMIC_CLASS (GogPolarSeries, gog_polar_series,
@@ -1060,7 +1320,7 @@ gog_color_polar_series_class_init (GogObjectClass *gog_klass)
GSF_DYNAMIC_CLASS (GogColorPolarSeries, gog_color_polar_series,
gog_color_polar_series_class_init, NULL,
- GOG_TYPE_RT_SERIES)
+ GOG_TYPE_POLAR_SERIES)
G_MODULE_EXPORT void
go_plugin_init (GOPlugin *plugin, GOCmdContext *cc)
diff --git a/plugins/plot_xy/gog-xy.c b/plugins/plot_xy/gog-xy.c
index aa2b5c9..66ed780 100644
--- a/plugins/plot_xy/gog-xy.c
+++ b/plugins/plot_xy/gog-xy.c
@@ -1192,9 +1192,10 @@ gog_xy_view_render (GogView *view, GogViewAllocation const *bbox)
GogErrorBar const *bar = series->x_errors;
if (gog_error_bar_get_bounds (bar, i - 1, &xerrmin, &xerrmax)) {
gog_error_bar_render (bar, view->renderer,
- x_map, y_map,
+ chart_map,
x, y,
- xerrmin, xerrmax, TRUE);
+ xerrmin, xerrmax,
+ GOG_ERROR_BAR_DIRECTION_HORIZONTAL);
}
}
@@ -1202,8 +1203,9 @@ gog_xy_view_render (GogView *view, GogViewAllocation const *bbox)
GogErrorBar const *bar = series->y_errors;
if (gog_error_bar_get_bounds (bar, i - 1, &yerrmin, &yerrmax)) {
gog_error_bar_render (bar, view->renderer,
- x_map, y_map, x, y,
- yerrmin, yerrmax, FALSE);
+ chart_map, x, y,
+ yerrmin, yerrmax,
+ GOG_ERROR_BAR_DIRECTION_VERTICAL);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]