[goffice] introduce two new view methods.
- From: Jean Bréfort <jbrefort src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [goffice] introduce two new view methods.
- Date: Mon, 9 Nov 2009 16:34:14 +0000 (UTC)
commit 3ee36cce49e11f49a01820c2e1cd65862d4f24eb
Author: Jean Brefort <jean brefort normalesup org>
Date: Mon Nov 9 17:30:45 2009 +0100
introduce two new view methods.
ChangeLog | 18 ++++++++
goffice/canvas/goc-graph.c | 1 +
goffice/data/go-data.c | 8 +++
goffice/graph/goffice-graph.h | 1 +
goffice/graph/gog-plot-impl.h | 7 ++-
goffice/graph/gog-plot.c | 20 +++++++++
goffice/graph/gog-plot.h | 3 +
goffice/graph/gog-view.c | 18 ++++++++
goffice/graph/gog-view.h | 6 ++-
plugins/plot_pie/gog-pie.c | 96 +++++++++++++++++++++++++++++++++++++++++
10 files changed, 174 insertions(+), 4 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a163400..7737b03 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2009-11-09 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/canvas/goc-graph.c (goc_graph_do_tooltip): use
+ gog_view_get_tip_at_point when no XY map is available (pies and rings).
+ * goffice/data/go-data.c (go_data_vector_get_str),
+ (go_data_matrix_get_str): load data before returning a string.
+ * goffice/graph/goffice-graph.h: move GogPlotView there.
+ * goffice/graph/gog-plot-impl.h: new gog_plot_view_get_data_at_point.
+ * goffice/graph/gog-plot.c (gog_plot_view_get_data_at_point): new function
+ introduced to fix #580545.
+ * goffice/graph/gog-plot.h: ditto.
+ * goffice/graph/gog-view.c (gog_view_get_tip_at_point): new function.
+ * goffice/graph/gog-view.h: ditto.
+ * plugins/plot_pie/gog-pie.c (gog_pie_view_get_data_at_point),
+ (gog_pie_view_get_tip_at_point), (gog_pie_view_class_init): implement the
+ two new view methods (only partially for now, does not work properly for
+ split rings).
+
2009-11-08 Jean Brefort <jean brefort normalesup org>
* goffice/utils/go-color.c (go_color_from_str): call gdk_parse_color when
diff --git a/goffice/canvas/goc-graph.c b/goffice/canvas/goc-graph.c
index c93e04d..2fccfae 100644
--- a/goffice/canvas/goc-graph.c
+++ b/goffice/canvas/goc-graph.c
@@ -306,6 +306,7 @@ goc_graph_do_tooltip (GocGraph *graph)
g_slist_free (l);
break;
default:
+ buf = gog_view_get_tip_at_point (view, x, y);
goto tooltip;
}
map = gog_chart_map_new (chart, &alloc, x_axis, y_axis, NULL, FALSE);
diff --git a/goffice/data/go-data.c b/goffice/data/go-data.c
index 15f77c5..0d3b2ca 100644
--- a/goffice/data/go-data.c
+++ b/goffice/data/go-data.c
@@ -707,6 +707,10 @@ go_data_vector_get_str (GODataVector *vec, unsigned i)
char *res;
g_return_val_if_fail (klass != NULL, g_strdup (""));
+ if (! (vec->base.flags & GO_DATA_CACHE_IS_VALID)) {
+ (*klass->load_values) (vec);
+ g_return_val_if_fail (vec->base.flags & GO_DATA_CACHE_IS_VALID, g_strdup (""));
+ }
g_return_val_if_fail ((int)i < vec->len, g_strdup (""));
res = (*klass->get_str) (vec, i);
@@ -883,6 +887,10 @@ go_data_matrix_get_str (GODataMatrix *mat, unsigned i, unsigned j)
char *res;
g_return_val_if_fail (klass != NULL, NULL);
+ if (! (mat->base.flags & GO_DATA_CACHE_IS_VALID)) {
+ (*klass->load_values) (mat);
+ g_return_val_if_fail (mat->base.flags & GO_DATA_CACHE_IS_VALID, g_strdup (""));
+ }
g_return_val_if_fail (((int)i < mat->size.rows) && ((int)j < mat->size.columns), g_strdup (""));
res = (*klass->get_str) (mat, i, j);
diff --git a/goffice/graph/goffice-graph.h b/goffice/graph/goffice-graph.h
index 75eb85e..582a988 100644
--- a/goffice/graph/goffice-graph.h
+++ b/goffice/graph/goffice-graph.h
@@ -37,6 +37,7 @@ typedef struct _GogPlot GogPlot; /* abstract base for plots */
typedef struct _GogPlotType GogPlotType; /* visible characterization */
typedef struct _GogPlotFamily GogPlotFamily; /* a group of plot types */
typedef struct _GogPlotDesc GogPlotDesc; /* data/axis requirements */
+typedef struct _GogPlotView GogPlotView;
typedef struct _GogSeries GogSeries; /* single plotable entity */
typedef struct _GogSeriesDesc GogSeriesDesc; /* data requirements */
typedef struct _GogSeriesDimDesc GogSeriesDimDesc; /* dimension of a series */
diff --git a/goffice/graph/gog-plot-impl.h b/goffice/graph/gog-plot-impl.h
index 640ba6f..4f17222 100644
--- a/goffice/graph/gog-plot-impl.h
+++ b/goffice/graph/gog-plot-impl.h
@@ -90,12 +90,15 @@ typedef struct {
#define GOG_TYPE_PLOT_VIEW (gog_plot_view_get_type ())
#define GOG_PLOT_VIEW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOG_TYPE_PLOT_VIEW, GogPlotView))
#define GOG_IS_PLOT_VIEW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOG_TYPE_PLOT_VIEW))
+#define GOG_PLOT_VIEW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GOG_TYPE_PLOT_VIEW, GogPlotViewClass))
-typedef struct _GogPlotView GogPlotView;
struct _GogPlotView {
GogView base;
};
-typedef GogViewClass GogPlotViewClass;
+typedef struct {
+ GogViewClass base;
+ int (*get_data_at_point) (GogPlotView *view, double x, double y, GogSeries **series);
+} GogPlotViewClass;
GType gog_plot_view_get_type (void);
G_END_DECLS
diff --git a/goffice/graph/gog-plot.c b/goffice/graph/gog-plot.c
index 565dd8c..be1a9f0 100644
--- a/goffice/graph/gog-plot.c
+++ b/goffice/graph/gog-plot.c
@@ -1240,3 +1240,23 @@ gog_plot_view_class_init (GogPlotViewClass *pview_klass)
GSF_CLASS_ABSTRACT (GogPlotView, gog_plot_view,
gog_plot_view_class_init, NULL,
GOG_TYPE_VIEW)
+
+
+/**
+ * gog_plot_view_get_data_at_point:
+ * @view : #GogPlotView
+ * @x : x position
+ * @y : y position
+ * @series: where to store the series
+ *
+ * Search a data represented at (@x,@y) in @view and set @series on success.
+ *
+ * return value: index of the found data in @series or -1.
+ **/
+int
+gog_plot_view_get_data_at_point (GogPlotView *view, double x, double y, GogSeries **series)
+{
+ GogPlotViewClass *klass = GOG_PLOT_VIEW_GET_CLASS (view);
+ g_return_val_if_fail (klass != NULL, -1);
+ return (klass->get_data_at_point)? klass->get_data_at_point (view, x, y, series): -1;
+}
diff --git a/goffice/graph/gog-plot.h b/goffice/graph/gog-plot.h
index 2144e2d..768f95e 100644
--- a/goffice/graph/gog-plot.h
+++ b/goffice/graph/gog-plot.h
@@ -71,6 +71,9 @@ void gog_plot_update_3d (GogPlot *plot);
void gog_plot_guru_helper (GogPlot *plot);
void gog_plot_clear_series (GogPlot *plot);
+int gog_plot_view_get_data_at_point (GogPlotView *view,
+ double x, double y, GogSeries **series);
+
G_END_DECLS
#endif /* GOG_PLOT_H */
diff --git a/goffice/graph/gog-view.c b/goffice/graph/gog-view.c
index cfdc55c..e656114 100644
--- a/goffice/graph/gog-view.c
+++ b/goffice/graph/gog-view.c
@@ -1002,3 +1002,21 @@ gog_view_get_view_at_point (GogView *view, double x, double y, GogObject **obj,
*obj = NULL;
return NULL;
}
+
+/**
+ * gog_view_get_tip_at_point:
+ * @view : #GogView
+ * @x : x position
+ * @y : y position
+ *
+ * Gets a tip string related to the position as defined by (@x,@y) in @view.
+ *
+ * return value: the newly allocated tip string if the view class supports
+ * that or NULL.
+ **/
+char*
+gog_view_get_tip_at_point (GogView *view, double x, double y)
+{
+ GogViewClass *klass = GOG_VIEW_GET_CLASS (view);
+ return (klass->get_tip_at_point != NULL)? (klass->get_tip_at_point) (view, x, y): NULL;
+}
diff --git a/goffice/graph/gog-view.h b/goffice/graph/gog-view.h
index 18a1446..ab347cc 100644
--- a/goffice/graph/gog-view.h
+++ b/goffice/graph/gog-view.h
@@ -91,6 +91,7 @@ typedef struct {
void (*render) (GogView *view, GogViewAllocation const *bbox);
void (*build_toolkit) (GogView *view);
+ char *(*get_tip_at_point) (GogView *view, double x, double y);
} GogViewClass;
#define GOG_TYPE_VIEW (gog_view_get_type ())
@@ -120,8 +121,9 @@ GogTool *gog_view_get_tool_at_point (GogView *view, double x, double y,
GogObject **gobj);
GogView *gog_view_get_view_at_point (GogView *view, double x, double y,
GogObject **obj, GogTool **tool);
-
-/* protected */
+char *gog_view_get_tip_at_point (GogView *view, double x, double y);
+
+ /* protected */
void gog_view_size_child_request (GogView *view,
GogViewRequisition const *available,
GogViewRequisition *req,
diff --git a/plugins/plot_pie/gog-pie.c b/plugins/plot_pie/gog-pie.c
index 677936c..fcfcfe0 100644
--- a/plugins/plot_pie/gog-pie.c
+++ b/plugins/plot_pie/gog-pie.c
@@ -631,6 +631,78 @@ typedef GogPlotViewClass GogPieViewClass;
static GogViewClass *pie_view_parent_klass;
+static int
+gog_pie_view_get_data_at_point (GogPlotView *view, double x, double y, GogSeries **series)
+{
+ GogPiePlot const *model = GOG_PIE_PLOT (view->base.model);
+ double r_max = view->base.allocation.h, cx, cy, r, h, theta, scale, *vals;
+ unsigned int index;
+ double center_size = 0.0;
+ unsigned num_series = 0;
+ double default_sep;
+ int ret = -1;
+ GSList *ptr;
+
+ /* compute number of valid series */
+ for (ptr = model->base.series ; ptr != NULL ; ptr = ptr->next) {
+ *series = ptr->data;
+ if (!gog_series_is_valid (GOG_SERIES (ptr->data)))
+ continue;
+ num_series++;
+ }
+
+ if (num_series <= 0)
+ return -1;
+
+ if (r_max > view->base.allocation.w)
+ r_max = view->base.allocation.w;
+ r_max /= 2.;
+ cx = view->base.allocation.x + view->base.allocation.w/2.;
+ cy = view->base.allocation.y + view->base.allocation.h/2.;
+ r = hypot (x - cx, y - cy);
+
+ if (r > r_max)
+ return -1;
+
+ if (GOG_IS_RING_PLOT (model))
+ center_size = GOG_RING_PLOT(model)->center_size;
+ /* FIXME: this is somewhat approximative, must be enhanced for ring plots with a slice separation */
+ center_size *= r_max;
+ if (r < center_size)
+ return -1;
+
+ default_sep = r_max * model->default_separation;
+ h = (r_max + default_sep - center_size) / num_series;
+ index = floor ((r - center_size) / h);
+ for (ptr = model->base.series ; ptr != NULL ; ptr = ptr->next) {
+ *series = ptr->data;
+ if (!gog_series_is_valid (GOG_SERIES (ptr->data)))
+ continue;
+ if (index-- == 0)
+ break;
+ }
+ theta = (atan2 (y - cy, x - cx)
+ * 180 / M_PI - model->initial_angle + 90.) / model->span / 3.6;
+ if (theta < 0)
+ theta += 1.;
+
+ vals = go_data_get_values ((*series)->values[1].data);
+ scale = 1 / GOG_PIE_SERIES (*series)->total;
+ for (index = 0 ; index < (*series)->num_elements; index++) {
+ r = vals[index] * scale;
+ if (r < 0.)
+ r = model->show_negatives? -r: 0.;
+ if (go_finite (r) && r > 1e-3) {
+ theta -= r;
+ if (theta < 0)
+ break;
+ }
+ }
+ /* using r to store the value */
+ return (int) index;
+ return ret;
+}
+
#define MAX_ARC_SEGMENTS 64
static void
@@ -914,13 +986,37 @@ gog_pie_view_build_toolkit (GogView *view)
#endif
}
+static char*
+gog_pie_view_get_tip_at_point (GogView *view, double x, double y)
+{
+ GogPieSeries *series = NULL;
+ int index = gog_pie_view_get_data_at_point (GOG_PLOT_VIEW (view), x, y, (GogSeries** )&series);
+ char *label, *ret;
+ double *vals, value;
+
+ if (index < 0)
+ return NULL;
+ vals = go_data_get_values (series->base.values[1].data);
+ value = fabs (vals[index]);
+ label = series->base.values[0].data? go_data_get_vector_string (series->base.values[0].data, index): NULL;
+ if (label && *label)
+ ret = g_strdup_printf (_("%s: %g (%.2f%%)"), label, value, value * 100 / series->total);
+ else
+ ret = g_strdup_printf (_("%g (%.2f%%)"), value, value * 100 / series->total);
+ g_free (label);
+ return ret;
+}
+
static void
gog_pie_view_class_init (GogViewClass *view_klass)
{
+ GogPlotViewClass *pv_klass = (GogPlotViewClass *) view_klass;
pie_view_parent_klass = g_type_class_peek_parent (view_klass);
view_klass->render = gog_pie_view_render;
view_klass->build_toolkit = gog_pie_view_build_toolkit;
+ view_klass->get_tip_at_point = gog_pie_view_get_tip_at_point;
+ pv_klass->get_data_at_point = gog_pie_view_get_data_at_point;
}
GSF_DYNAMIC_CLASS (GogPieView, gog_pie_view,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]